// ==UserScript==
// @name           LoU Tweak
// @description    Adds various functionalities to Lord of Ultima
// @namespace      AmpliDude
// @include        http://prodgame*.lordofultima.com/*/index.aspx*
// @version        1.7.4
// @require        http://sizzlemctwizzle.com/updater.php?id=80532&days=1
// @grant 		   none
// ==/UserScript==

(function(){

var LT_mainFunction = function() {

	function createTweak() {
		var LTversion = "1.7.4";
		var louTweak = {};
		var LT = {};
		
		LT_strings = {
			"0": { /* english */
				"options_btn_tt": "Click to show LoU Tweak Options",
				"layout_btn_tt": "Click to generate layout Sharestring for current city",
				"chat_btn_city": "City",
				"chat_btn_player": "Player",
				"chat_btn_alliance": "Alliance",
				"chat_btn_url": "Link",
				"copy_coords_btn": "Copy coordinates to chat",
				"up_count_tt": "Buildings available for upgrade:",
				"opts_max_chatlines": "Maximum lines of chat:",
				"opts_chat_opacity": "Chat background transparency:",
				"opts_switch_to_ally_tab": "Switch to Alliance Tab at start",
				"opts_show_queue_win": "Show queue info window",
				"opts_limit_req_res": "Limit requested resources to city free space",
				"opts_inc_res": {
					"lab": "Incoming resources label:",
					"disabled": "Disabled",
					"always": "Always on",
					"context": "Contextual"
				},
				"opts_separator": {
					"lab": "Thousands separator:",
					"period": "'.' (period)",
					"comma": "',' (comma)",
					"space": "' ' (space)",
					"none": "none"
				},
				"opts_city_tag": {
					"lab": "[city] tag shows:",
					"info": "City info",
					"region": "Region view"
				},
				"opts_lowest_lvl": {
					"lab1": "Select buildings that you want to upgrade with 'L (upgrade any lowest level)' shortcut",
					"lab2": "Define Max levels of every group type at which shortcut 'L' will stop upgrading",
					"towers": "Towers:",
					"military": "Military:",
					"resource": "Resource:",
					"cottage": "Cottage:",
					"barracks": "Barracks:",
					"utilities": "Utilities:"
				},
				"opts_set_hotkeys": "Click on one of the following buttons and then press a key to define shortcut",
				"opts_hotkey_labels": {
					"lab1": "Build hotkeys:",
					"lab2": "Upgrade hotkeys:",
					"lab3": "Moonstone creation hotkeys:",
					"lab4": "Global hotkeys:",
					"upgrade": "Upgrade building",
					"downgrade": "Downgrade / Demolish (Shift+)",
					"minister": "Assign to Minister",
					"prev_city": "Previous city",
					"next_city": "Next city"
				},
				"opts_clr_inc_res": "Incoming resources label font colors:",
				"opts_clr_chat": {
					"lab": "Chat font colors:",
					"all": "All:",
					"alliance": "Alliance:",
					"whisper": "Whisper ",
					"background": "Background:",
					"social": "Social:",
					"louwin": "LoU:"
				},
				"opts": {
					"save": "Save",
					"export": "Export",
					"import": "Import",
					"export_lab": "You can save this string in a text file and import it later when needed.",
					"import_lab": "Insert saved LoU Tweak Options into text field and press OK.",
					"import_invalid": "Inserted string is invalid"
				},
				"layout": {
					"city": "City layout",
					"overlay": "Overlay layout",
					"apply": "Apply layout",
					"remove": "Remove layout"
				},
				"opts_lang": {
					"lab": "LoU Tweak language",
					"en": "English (Englisch)",
					"de": "German (Deutsch)",
					"es": "Spanish (Español)",
					"pl": "Polish (Polski)",
					"pt": "Portuguese (Português)",
					"ru": "Russian (Русский)",
					"it": "Italian (Italiano)",
					"fr": "French (Français)"
				},
				"purify_btn_tt": "Click to open 'Purify resources' window",
				"opts_minimap": {
					"enable_lab": "Enable MiniMap",
					"clrs_lab": "MiniMap colors:",
					"show_cities": "Show cities",
					"show_none": "None",
					"show_noncastle": "Non-castle",
					"show_castle": "Castle",
					"show_all": "All",
					"show_self": "My",
					"show_alliance": "Alliance",
					"show_allied": "Allied",
					"show_enemy": "Enemy",
					"show_nap": "NAP",
					"show_other": "Other",
					"show_lawless": "Lawless",
					"show_moongate": "Moongates",
					"show_shrine": "Shrines",
					"clr_self": "Self:",
					"clr_alliance": "Alliance:",
					"clr_allied": "Allied:",
					"clr_enemy": "Enemy:",
					"clr_nap": "NAP:",
					"clr_other": "Other:",
					"clr_lawless": "Lawless:",
					"clr_moongate": "Moongate:",
					"clr_shrine": "Shrine:"
				},
				"trade_limit": "Limit",
				"no": "No",
				"yes": "Yes",
				"req_restart": "(requires restart)",
				"opts_save_ss_cn": "Save overlay layout Sharestring in city notes",
				"opts_trade_lab_max_amount": "Amount of Trade Summary labels to be displayed:",
				"show_get_use_btn_tt": "Show 'Get & Use' buttons",
				"opts_hide_get_use": "Hide 'Get & Use' buttons",
				// OPTIMIZE
				"show_optimize_btn_tt": "Show Optimize buttons",
				"opts_hide_optimize": "Hide Optimize buttons",
				//
				"btn_trade_show": "Show Trade Summary labels",
				"btn_trade_hide": "Hide Trade Summary labels",
				"btn_support_show": "Show Support labels",
				"btn_support_hide": "Hide Support labels"
			}
		};
		function L(str) {
			return LT_strings[window.louTweak.main.getInstance().getLang()][str];
		}
		
		qx.Class.define("louTweak.main", {
			type: "singleton",
			extend: qx.core.Object,
			statics: {
				lou_building_id: {
					"woodcutter": 47, "quarry": 48, "farm": 50, "cottage": 4, "market": 5, "ironmine": 49, "sawmill": 7, "mill": 8, "hideout": 9, "stonemason": 10, "foundry": 11, "townhouse": 13, "barracks": 14, "cityguardhouse": 15, "trainingground": 16, "stable": 17, "workshop": 18, "shipyard": 19, "warehouse": 20, "castle": 21, "harbor": 22, "moonglowtower": 36, "trinsictemple": 37, "lookouttower": 38, "ballistatower": 39, "guardiantower": 40, "rangertower": 41, "templartower": 42, "pitfalltrap": 43, "barricade": 44, "arcanetrap": 45, "camouflagetrap": 46
				},
				bd: {
/* woodcutter */		"1": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 1},
/* quarry */			"2": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 2},
/* farm */				"3": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 3},
/* cottage */			"4": {"w": [ 0, 0, 0, 0, 200, 500, 1000, 2000, 5000, 12000 ], "s": [ 50, 150, 300, 600, 1000, 2000, 4000, 7500, 14000, 17000 ], "th": 1},
/* marketplace */		"5": {"w": [ 40, 80, 160, 400, 1200, 2800, 5600, 9600, 15200, 23200 ], "s": [ 20, 40, 80, 200, 600, 1400, 2800, 4800, 7600, 11600 ], "th": 5},
/* iron mine */			"6": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 4},
/* sawmill */			"7": {"w": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "s": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "th": 6},
/* mill */				"8": {"w": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "s": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "th": 8},
/* hideout */			"9": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],"s": [ 50, 200, 600, 1000, 1500, 2200, 3500, 4500, 6000, 8000 ], "th": 2},
/* stonemason */		"10": {"w": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "s": [ 60, 150, 350, 1100, 2700, 5000, 7800, 13500, 21500, 33000 ], "th": 7},
/* foundry */			"11": {"w": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "s": [ 60, 150, 350, 1100, 2700, 5000, 8500, 13500, 21500, 33000 ], "th": 9},
/* town hall */			"12": {"w": [ 0, 200, 500, 1000, 3000, 8000, 15000, 30000, 60000, 120000 ], "s": [ 0, 0, 100, 300, 1500, 4000, 10000, 25000, 60000, 120000 ], "th": 0},
/* townhouse */			"13": {"w": [ 0, 0, 0, 0, 1000, 2000, 3500, 7000, 14000, 29000 ], "s": [ 100, 300, 600, 2000, 4000, 7000, 11500, 17000, 24000, 29000 ], "th": 5},
/* barracks */			"14": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],"s": [ 50, 150, 300, 600, 1200, 2500, 4000, 7000, 11500, 17500 ], "th": 4},
/* city guard house */	"15": {"w": [ 15, 30, 55, 140, 400, 1000, 1900, 3200, 5100, 8000 ], "s": [ 30, 60, 110, 280, 800, 2000, 3800, 6400, 10200, 16000 ], "th": 3},
/* training ground */	"16": {"w": [ 20, 40, 80, 200, 600, 1400, 2800, 4800, 7500, 11500 ], "s": [ 40, 80, 160, 400, 1200, 2800, 5600, 9600, 15000, 23000 ], "th": 4},
/* stable */			"17": {"w": [ 25, 55, 110, 275, 800, 1900, 3750, 6500, 10200, 15500 ], "s": [ 50, 110, 220, 550, 1600, 3800, 7500, 13000, 20400, 31000 ], "th": 6},
/* workshop */			"18": {"w": [ 40, 75, 150, 370, 1100, 2600, 5200, 8900, 14000, 21500 ], "s": [ 80, 150, 300, 740, 2200, 5200, 10400, 17800, 28000, 43000 ], "th": 9},
/* shipyard */			"19": {"w": [ 50, 100, 200, 500, 1500, 3500, 7000, 12000, 19000, 29000 ], "s": [ 100, 200, 400, 1000, 3000, 7000, 14000, 24000, 38000, 58000 ], "th": 10},
/* warehouse */			"20": {"w": [ 60, 150, 250, 500, 1600, 3000, 6000, 9600, 15000, 20000 ], "s": [ 0, 0, 50, 150, 400, 1000, 2000, 4800, 9000, 13000 ], "th": 1},
/* castle */			"21": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 20000, 25000, 30000, 40000, 55000, 75000, 100000, 130000, 160000, 200000 ], "th": 8},
/* harbor */			"22": {"w": [ 80, 160, 320, 800, 2400, 5600, 11200, 19200, 30400, 46400 ], "s": [ 40, 80, 160, 400, 1200, 2800, 5600, 9600, 15200, 23200 ], "th": 10},
/* wall */				"23": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 200, 2000, 8000, 20000, 30000, 45000, 70000, 100000, 140000, 200000 ], "th": 2},
/* moonglow tower */	"36": {"w": [ 30, 60, 120, 300, 900, 2100, 4200, 7200, 11400, 17400 ], "s": [ 60, 120, 240, 600, 1800, 4200, 8400, 14400, 22800, 34800 ], "th": 7},
/* trinsic temple */	"37": {"w": [ 35, 70, 135, 335, 1000, 2350, 4650, 8000, 12700, 19500 ], "s": [ 70, 140, 270, 670, 2000, 4700, 9300, 16000, 25400, 39000 ], "th": 8},
/* lookout tower */		"38": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 200, 400, 600, 1000, 1500, 2200, 3500, 5000, 7500, 10000 ], "th": 2},
/* ballista tower */	"39": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 100, 200, 400, 1000, 3000, 7000, 14000, 24000, 38000, 58000 ], "th": 9},
/* guardian tower */	"40": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 100, 200, 400, 1000, 3000, 7000, 14000, 24000, 38000, 58000 ], "th": 6},
/* ranger tower */		"41": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 100, 200, 400, 1000, 3000, 7000, 14000, 24000, 38000, 58000 ], "th": 3},
/* templar tower */		"42": {"w": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "s": [ 100, 200, 400, 1000, 3000, 7000, 14000, 24000, 38000, 58000 ], "th": 8},
/* pitfall trap */		"43": {"w": [ 30, 60, 110, 280, 830, 1930, 3850, 6600, 10500, 16000 ], "s": [ 90, 180, 330, 840, 2490, 5790, 11550, 19800, 31500, 48000 ], "th": 5},
/* barricade */			"44": {"w": [ 30, 60, 110, 280, 830, 1930, 3850, 6600, 10500, 16000 ], "s": [ 90, 180, 330, 840, 2490, 5790, 11550, 19800, 31500, 48000 ], "th": 7},
/* arcane trap */		"45": {"w": [ 30, 60, 110, 280, 830, 1930, 3850, 6600, 10500, 16000 ], "s": [ 90, 180, 330, 840, 2490, 5790, 11550, 19800, 31500, 48000 ], "th": 8},
/* camouflage trap */	"46": {"w": [ 30, 60, 110, 280, 830, 1930, 3850, 6600, 10500, 16000 ], "s": [ 90, 180, 330, 840, 2490, 5790, 11550, 19800, 31500, 48000 ], "th": 10},
/* woodcutter */		"47": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 1},
/* quarry */			"48": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 2},
/* iron mine */			"49": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 4},
/* farm */				"50": {"w": [ 50, 200, 400, 1400, 3500, 6000, 10000, 16000, 25000, 38000 ], "s": [ 0, 0, 200, 600, 1500, 3000, 5000, 8000, 13000, 20000 ], "th": 3},
				}
			},
			members: {
				app: null,
				chat: null,
				titleW: null,
				cBar: null,
				srvBar: null,
				cInfoView: null,
				cDetView: null,
				dDetView: null,
				ncView: null,
				bDetView: null,
				bPlaceDetView: null,
				bQc: null,
				bQcSpdLab: null,
				bQh: null,
				city: null,
				cityId: null,
				originalConvertBBCode: null,
				createdTopBottomButtons: null,
				topBottomButtonsListener: null,
				tradeButtonsListener: null,
				temp_limit: null,
				lang: null,
				options: null,
				optionsPage: null,
				layoutWindow: null,
				miniMap: null,
				qtLab: null,
				OptimizationOverlay: null,
				timer: null,
				lastSendCommand: null,
				sendCommandBuffer: null,
				sendCommandBusy: null,
				reportPageListener: null,
				cTradeInfoView: null,
				getUseBtnVisibility: null,
				getOptimizeBtnVisibility: null,
				getOptimize: null,
				getUseCont1: null,
				getUseCont2: null,
				getUseCont3: null,
				cCmdInfoView: null,
				moveBuildingDetView: null,
				initialize: function() {
					if (typeof qx.lang.Json == "undefined")
						qx.lang.Json = qx.util.Json;
					if (typeof webfrontend.ui.SpinnerInt == "undefined")
						webfrontend.ui.SpinnerInt = webfrontend.gui.SpinnerInt;
					
					this.app = qx.core.Init.getApplication();

					this.cInfoView = this.app.cityInfoView;
					
					this.chat = this.app.chat;
					
					this.bQc = this.cInfoView.buildingQueue;
					this.bQh = this.bQc.header;
					this.bQcSpdLab = this.bQc.constructionSpeedLabel;
					
					this.bDetView = this.app.getBuildingDetailView();
					this.bPlaceDetView = this.app.getBuildingPlaceDetailView();
					
					this.cDetView = this.app.cityDetailView || this.app.getCityDetailView();
					this.dDetView = this.app.dungeonDetailView || this.app.getDungeonDetailView();
					this.ncView = this.app.newCityView || this.app.getNewCityView();
					
					this.titleW = this.app.title;
					this.cBar = this.app.cityBar;
					this.srvBar = this.app.serverBar;
					
					this.lang = qx.locale.Manager.getInstance().getLocale();
					if (!/en|de|es|pl|pt|pt_BR|ru|it/.test(this.lang)) this.lang = "en";
					
					this.createdTopBottomButtons = 0;
					this.getUseBtnVisibility = "visible";
					
					this.timer = qx.util.TimerManager.getInstance();
					this.lastSendCommand = 0;
					this.sendCommandBuffer = new Array();
					this.sendCommandBusy = false;
					civ_ch = this.cInfoView.container.getChildren();
					for (i=0; i<civ_ch.length; i++) {
						if (civ_ch[i] instanceof webfrontend.gui.CityTradeInfoView)
							this.cTradeInfoView = civ_ch[i];
					}
					this.moveBuildingDetView = this.app.getMoveBuildingDetailView();
					this.tweakLoU();
				},
				tweakLoU: function() {
		// try {
					_LT = LT;
					this.loadOptions();
					if (this.options.userLang == "") this.options.userLang = this.lang;
					else this.setLang(this.options.userLang);
					LT.options = this.options;
					LT.srvTime = webfrontend.data.ServerTime.getInstance().refTime; // reference time (server start date in milisec?)
					LT.debug = this.debug;
					LT.thSep = this.thSep;
					LT.a = this.app;
					LT.main = this;
					
					this.miniMap = new window.louTweak.miniMap();
					if (!this.app.getSelectorBar().isMapSelectorBarAnchorToLeft()) {
						this.app.desktop.add(this.miniMap.clientArea, {right: 0, top: 133});
					} else {
						this.app.desktop.add(this.miniMap.clientArea, {right: 0, top: 62});
					}
					if (!LT.options.showMiniMap)
						LT.main.miniMap.clientArea.setVisibility("excluded");
			
					this.app.visMain.addListener("changeMapLoaded", this.miniMap.updateCameraPos, this.miniMap);
					webfrontend.data.City.getInstance().addListener("changeVersion", this.miniMap.updateCameraPos, this.miniMap); // hack to redraw map in region view while switching cities
					qx.bom.Element.addListener(this.app.worldView, "mouseup", LT.main.miniMap.updateCameraPos, this.miniMap);
					
					// ***** Options button ***** //
					btn = new qx.ui.form.Button("O");
					btn.set({width: 30, appearance: "button-text-small", toolTipText: L("options_btn_tt")});
					btn.addListener("click", this.showOptionsPage, this);
					this.srvBar.add(btn, {top: 2, left: 390});
					
					// ***** City layout button ***** //
					btn = new qx.ui.form.Button("L");
					btn.set({width: 25, appearance: "button-text-small", toolTipText: L("layout_btn_tt")});
					btn.addListener("click", function(){this.layoutWindow.generateSharestring(); this.layoutWindow.open();}, this);
					this.bQh.add(btn, {top: 33, left: 305});
					// make the button disabled if in region view
					this.app.visMain.addListener("changeMapLoaded", function() { this.setEnabled(LT.a.visMain.mapmode == "c" ? true : false); }, btn);
					
					// ***** Purify resources window button ***** //
					btn = new qx.ui.form.Button("P");
					btn.set({width: 25, appearance: "button-text-small", toolTipText: L("purify_btn_tt")});
					btn.addListener("click", this.showPurifyWindow, this);
					this.bQh.add(btn, {top: 33, left: 275});
					
					// ***** Show 'Get & use' buttons ***** //
					btn = new qx.ui.form.Button("A");
					btn.set({width: 25, appearance: "button-text-small", toolTipText: L("show_get_use_btn_tt"), visibility: "excluded"});
					btn.addListener("click", function() {
						if (this.getUseBtnVisibility == "visible")
							this.getUseBtnVisibility = "excluded";
						else
							this.getUseBtnVisibility = "visible";
							this.showGetUseButtons();
					}, this);
					this.bQh.add(btn, {top: 33, left: 8});
					this.app.setUserData("showGetUseBtn", btn);
					
					// ***** Show 'Optimize' buttons ***** //
					btn = new qx.ui.form.Button("O");
					btn.set({width: 25, appearance: "button-text-small", toolTipText: L("show_optimize_btn_tt"), visibility: "excluded"});
					btn.addListener("click", function() {
						if (this.OptimizeBtnVisibility == "visible")
							this.OptimizeBtnVisibility = "excluded";
						else
							this.OptimizeBtnVisibility = "visible";
							this.showOptimizationOverlay();
					}, this);
					this.bQh.add(btn, {top: 33, left: 38});
					//this.app.setUserData("showGetUseBtn", btn);
					this.app.setUserData("showOptimizeBtn", btn);

					// ***** 'Show/Hide Trade Summary labels' button ***** //
					btn = new qx.ui.form.Button(null, "webfrontend/theme/scrollbar/scrollbar-up.png");
					btn.set({width: 30, height: 20, appearance: "button-brown-sort", toolTipText: L("btn_trade_hide")});
					btn.addListener("click", function() {
						if (LT.main.cTradeInfoView._getChildren()[2].getVisibility() == "visible") {
							LT.main.cTradeInfoView._getChildren()[2].setVisibility("excluded");
							this.set({toolTipText: L("btn_trade_show"), icon: "webfrontend/theme/scrollbar/scrollbar-down.png"});
						} else {
							LT.main.cTradeInfoView._getChildren()[2].setVisibility('visible');
							this.set({toolTipText: L("btn_trade_hide"), icon: "webfrontend/theme/scrollbar/scrollbar-up.png"});
						}
					}, btn);
					LT.main.cTradeInfoView._getChildren()[0].add(btn, {top: 7, left: 140});

					
					// ***** 'Show/Hide Support Container' button ***** //
					civ_cont = this.cInfoView.container.getChildren();
					for (i=0; i<civ_cont.length; i++) {
						if (civ_cont[i].basename == "CityCommandInfoView") {
							this.cCmdInfoView = civ_cont[i];
							break;
						}
					}
					btn = new qx.ui.form.Button(null, "webfrontend/theme/scrollbar/scrollbar-up.png");
					btn.set({width: 30, height: 20, appearance: "button-brown-sort", toolTipText: L("btn_support_hide")});
					btn.addListener("click", function() {
						if (LT.main.cCmdInfoView.supports.getVisibility() == "visible") {
							LT.main.cCmdInfoView.supports.setVisibility("excluded");
							this.set({toolTipText: L("btn_support_show"), icon: "webfrontend/theme/scrollbar/scrollbar-down.png"});
						} else {
							LT.main.cCmdInfoView.supports.setVisibility('visible');
							this.set({toolTipText: L("btn_support_hide"), icon: "webfrontend/theme/scrollbar/scrollbar-up.png"});
						}
					}, btn);
					this.cCmdInfoView.supportHeaderData.header.add(btn, {top: 7, left: 210});

					// ***** BBCode buttons in chat window ***** //
					cont = new qx.ui.container.Composite(new qx.ui.layout.Grid());

					btns = [
						{lab: L("chat_btn_city"), func: this.parseCoords},
						{lab: L("chat_btn_player"), func: function() {this.parseText("player")}},
						{lab: L("chat_btn_alliance"), func: function() {this.parseText("alliance")}},
						{lab: L("chat_btn_url"), func: function() {this.parseText("url")}}
					];
					for (i=0; i<btns.length; i++) {
						btn = new qx.ui.form.Button(btns[i].lab).set({appearance: "button-text-small", padding: [0,3,0,3]});
						btn.addListener("click", btns[i].func, this);
						cont.add(btn, {row: Math.floor(i/2), column: i%2});
					}
					this.chat.add(cont, {top: 0, left: 275});

					// ***** Copy City Coords To Chat buttons ***** //
					btn = new qx.ui.form.Button(L("copy_coords_btn")).set({maxWidth:160, height: 32, alignX: "center", paddingLeft: 2, paddingRight: 2});
						btn.addListener("click", function() {this.copyCoordsToChat("c")}, this);
					this.cDetView.actionArea.add(btn, {left:86, top: 130});
					btn = new qx.ui.form.Button(L("copy_coords_btn")).set({width:160, height: 32, paddingLeft: 2, paddingRight: 2});
						btn.addListener("click", function() {this.copyCoordsToChat("d")}, this);
					this.dDetView.actionArea.add(btn, {left:86, top: 110});
					btn = new qx.ui.form.Button(L("copy_coords_btn")).set({maxWidth:160, height: 32, alignX: "center", paddingLeft: 2, paddingRight: 2});
						btn.addListener("click", function() {this.copyCoordsToChat("n")}, this);
					this.ncView.container.add(new qx.ui.core.Spacer(0,30));
					this.ncView.container.add(btn);

					// ***** Queue times label ***** //
					this.qtLab = new window.louTweak.queueTimesLabel();
					if (this.app.selectorBar.isMapSelectorBarAnchorToLeft()) {
						this.app.desktop.add(this.qtLab.queueTimeCont, {left: 690, top: 65});
					} else {
						this.app.desktop.add(this.qtLab.queueTimeCont, {left: 405, top: 65});
					}
			
					// ***** Incoming resources label ***** //
					lab = new window.louTweak.incomingResourcesLabel();
					this.bQc.getLayoutParent().addBefore(lab.incResCont, this.bQc);

					// ***** Switch to ally tab on start ***** //
					if (this.options.switchToAllyTab)
						this.chat.tabView.setSelection([this.chat.tabView.getChildren()[1]]);

					// ***** Listeners ***** //
					// app keyboard
					this.app.mainContainer.addListener("keypress", this.appPerformAction, this);
					// scene keyboard
					this.app.visMain.scene.getOutputWidget().addListener("keypress", this.scenePerformAction, this);
			
					webfrontend.data.City.getInstance().addListener("changeVersion", this.countUpgradeable, this);

					webfrontend.data.City.getInstance().addListener("changeVersion", this.showGetUseButtons, this);
					this.cInfoView.addListener("appear", this.showGetUseButtons, this);
					if (this.cInfoView.quickUseBuildingItemBtn != null) {
						this.cInfoView.quickUseBuildingItemBtn.addListener("appear", this.showGetUseButtons, this);
					} else {
						for (var p in this.cInfoView) {
							if (this.cInfoView[p] != null && (this.cInfoView[p].basename == "SoundButton" || this.cInfoView[p].basename == "QuickUseButton")) {
								if (this.cInfoView[p].getAppearance() == "button-quickuse") {
									glp = this.cInfoView[p].getLayoutParent();
									if (this.getUseCont1 == null) {
										this.getUseCont1 = glp;
										continue;
									}
									if (this.getUseCont2 == null) {
										if (this.getUseCont1 != glp) {
											this.getUseCont2 = glp;
										}
										continue;
									}
									if (this.getUseCont2 != glp && this.getUseCont3 == null) {
										this.getUseCont3 = glp;
										break;
									}
								}
							}
						}
					}

					//this.topBottomButtonsListener = webfrontend.base.Timer.getInstance().addListener("uiTick", this.updateTopBottomButtons, this);
					this.tradeButtonsListener = webfrontend.base.Timer.getInstance().addListener("uiTick", this.createTradeButtons, this);
					webfrontend.base.Timer.getInstance().addListener("uiTick", this.updateMiniMapButton, this);
					this.reportPageListener = this.app.getReportPage().reportBody.addListenerOnce("addChildWidget", this.tweakReport, this);
					
					// ***** Chat colors ***** //
					chatIns = webfrontend.config.Config.getInstance().getChat();
					chatIns.channelColors.global = this.options.chatColors[0];
					chatIns.channelColors._a = this.options.chatColors[1];
					chatIns.channelColors.privatein = this.options.chatColors[3];
					chatIns.channelColors.privateout = this.options.chatColors[4];
					chatIns.channelColors.social = this.options.chatColors[5];
					chatIns.channelColors.LoUWin = this.options.chatColors[6];
					chatIns.setMaxLines(this.options.chatMaxLines);
					
					this.chat.BgrLabel.setBackgroundColor(this.options.chatColors[2]);
					this.chat.BgrLabel.setOpacity((parseInt(this.options.chatOpacity))/100);

					this.tweakInterface();

					this.optionsPage = new window.louTweak.optionsPage();
					this.OptimizationOverlay = new window.louTweak.OptimizationOverlay();
					
					this.layoutWindow = new window.louTweak.layoutWindow();

					this.app.visMain.addListener("changeMapLoaded", function(){this.tabView.setSelection([this.tabView.getChildren()[0]]); this.win.close(); this.showOverlayLayout();}, this.layoutWindow);
					this.getCity();
					//
					
					this.originalConvertBBCode = webfrontend.gui.Util.convertBBCode;
					webfrontend.gui.Util.convertBBCode = this.newConvertBBCode;
		// } catch (e) {
			// console.log(e);
		// }
				},
				appPerformAction: function(e) {
					if (!this.app.allowHotKey || this.bDetView.visBuilding != null || this.bPlaceDetView.active || this.app.currentOverlay != null || this.app.cityBar.citiesSelect.getSelectables()[0].getLayoutParent().getLayoutParent().getLayoutParent().getLayoutParent().isVisible()) {
						return;
					}
					key = e.getKeyIdentifier();
					if (key == "") return;
					shft = e.isShiftPressed();
					ctrl = e.isCtrlPressed();
					
					if (key == this.options.hotkeys.global.prevcity)
						this.cBar.prevButton.execute();
					else if (key == this.options.hotkeys.global.nextcity)
						this.cBar.nextButton.execute();
					
					if (this.app.visMain.mapmode != "c" || this.sendCommandBusy) return;
					switch (key) {
						case 'T':
							this.upgradeLowestLevelBuilding("T", shft);
							break;
						case 'N':
							this.upgradeLowestLevelBuilding("M", shft);
							break;
						case 'B':
							this.upgradeLowestLevelBuilding("B", shft);
							break;
						case 'C':
							this.upgradeLowestLevelBuilding("C", shft);
							break;
						case 'L':
							this.upgradeLowestLevelBuilding("A", shft);
							break;
						case 'E':
							this.upgradeLowestLevelBuilding("R", shft);
							break;
						case 'U':
							this.upgradeLowestLevelBuilding("U", shft);
							break;
						case 'Q':
							if (shft)
								this.upgradeLowestLevelBuilding("F", false);
							break;
						case 'A':
							if (shft)
								this.upgradeLowestLevelBuilding("F", true);
							break;
						default:
							return;
					}
				},
				scenePerformAction: function(e) {
					if (this.app.visMain.mapmode != "c" || this.sendCommandBusy) return;
					
					key = e.getKeyIdentifier();
					shft = e.isShiftPressed();

					if (this.moveBuildingDetView.active && this.moveBuildingDetView.placeId != null) {
						this.moveBuildingDetView._onMoveBuildingQuickUse();
						return;
					}
					if (!this.bDetView.visBuilding) {
						if (this.bPlaceDetView.active) {
							if (/\b(27|28|29|30|60|61|62|63)\b/.test(this.bPlaceDetView.buildingType) && key == this.options.hotkeys.upgrades.downgrade) {
								this.bPlaceDetView.downgradeButton.execute(); // destroy resource
								return;
							} else {
								for (var i in this.options.hotkeys.build) {
									if (this.options.hotkeys.build[i] == key) {
										_bid = this.self(arguments).lou_building_id[i];
										if (this.bPlaceDetView.buildingInfo[_bid].canBuild) {
											this.cityObject("Build", this.bPlaceDetView.placeId, _bid, 1, false);
											return;
										}
									}
								}
							}
						}
					}
					if (this.bDetView.visBuilding) {
					try {
						_bid = this.bDetView.visBuilding.getId();
						_ind = this.getIndex(_bid);
						if (_ind == -1) return;
						_btype = this.city[_ind][2];
						if (/\b(27|28|29|30|60|61|62|63)\b/.test(_btype)) return;
						_blvl = this.city[_ind][1];
						if (_blvl < 0) return;
						if (/\b(1|2|3|4|5|6|7|8|9)\b/.test(key)) {
							if (this.isAssignedToMinister(_bid)) return;
							_ups = (RegExp.$1 == "1" ? 10 - _blvl : parseInt(RegExp.$1) - _blvl);
							if (_ups <= 0) return;
							au = this.availUpgrades(_btype, _blvl, _ups);
							this.cityObject("UpgradeBuilding", _bid, _btype, au, false);
							return;
						}
						au = 10;
						_ups = shft ? au - _blvl : 1;
						if (key != this.options.hotkeys.upgrades.minister) {
							if (this.isAssignedToMinister(_bid)) return;
							au = this.availUpgrades(_btype, _blvl, _ups);
						} else
							au = _ups;
						switch (key) {
							case this.options.hotkeys.upgrades.upgrade:
								this.cityObject("UpgradeBuilding", _bid, _btype, au, false);
								break;
							case this.options.hotkeys.upgrades.downgrade:
								au = shft ? 10 : 1;
								this.cityObject("DowngradeBuilding", _bid, _btype, au, false);
								break;
							case this.options.hotkeys.upgrades.minister:
								this.cityObject("UpgradeBuilding", _bid, _btype, au, true);
								break;
							case 'M':
								this.bDetView.quMoveBuilding.btn.execute();
								break;
							default:
								return;
						}
					} catch (e) { LT.debug(e); }
				}
				},
				cityObject: function(_action, _buildingId, _buildingType, _upgrades, _minister) {
					if (_upgrades <= 0) return;

					bqmax = webfrontend.data.Player.getInstance().getMaxBuildQueueSize();
					bqcur = webfrontend.data.City.getInstance().buildQueue;
					bqcur = (bqcur != null) ? bqcur.length : 0;
					freeSlots = bqmax - bqcur;
					if (freeSlots == 0) return;
					if (freeSlots < _upgrades && _action != "DowngradeBuilding") _upgrades = freeSlots;
					
					if (_action == "Build") {
						if (_buildingType == 21 && this.bPlaceDetView.active) {
							this.bPlaceDetView.buildingType = 21;
							this.bPlaceDetView._onClickBuild();
							return;
						}
						_action = "UpgradeBuilding";
					}
					
					if (_action == "DowngradeBuilding" && _upgrades == 10) {
						_action = "DemolishBuilding";
						_upgrades = 1;
					}
					_cid = webfrontend.data.City.getInstance().getId()
					for (o=0; o<_upgrades; o++) {
						//console.log({a:_action, p:{cityid: _cid, buildingid: _buildingId, buildingType: _buildingType, isPaid: !_minister}});
						this.sendCommandBuffer.push({a:_action, p:{cityid: _cid, buildingid: _buildingId, buildingType: _buildingType, isPaid: !_minister}});
					}
					if (!this.sendcommandBusy) {
						this.sendCommandBusy = true;
						this.sendCmd();
					}
				},
				sendCmd: function() {
					if (this.sendCommandBuffer.length == 0) {
						this.sendCommandBusy = false;
						return;
					}
					currentTime = new Date().getTime();
					if (currentTime > this.lastSendCommand+500) {
						cmd = this.sendCommandBuffer.shift();
						//LT.debug(cmd.a + ", " + cmd.p);
						webfrontend.net.CommandManager.getInstance().sendCommand(cmd.a, cmd.p, this, function(){});
						this.lastSendCommand = currentTime;
					}
					this.timer.start(this.sendCmd, null, this, null, 250);
				},
				availUpgrades: function(bt, bl, bu) {
					c = webfrontend.data.City.getInstance();
					th = c.getTownhallLevel();
					if (this.self(arguments).bd[bt].th > th)
						return 0;
					wood = c.getResourceCount(1);
					stone = c.getResourceCount(2);
					u = 0;
					while (bu > 0) {
						wn = this.self(arguments).bd[bt].w[bl];
						sn = this.self(arguments).bd[bt].s[bl];
						if (wn > wood || sn > stone) break;
						wood -= wn;
						stone -= sn;
						u++;
						bl++;
						bu--;
					}
					return u;
				},
				isAssignedToMinister: function(bid) {
					cBuildQueue = webfrontend.data.City.getInstance().getBuildQueue();
					if (cBuildQueue != null) {
						for (m=0; m<cBuildQueue.length; m++) {
							if (cBuildQueue[m].building == bid && cBuildQueue[m].isPaid == false) return true;
						}
					}
					return false;
				},
				upgradeLowestLevelBuilding: function(_type, _minis) {
					if (this.app.visMain.mapmode != "c") return;

					c = webfrontend.data.City.getInstance();
					tw = parseInt(c.getResourceCount(1));
					ts = parseInt(c.getResourceCount(2));
					bqmax = webfrontend.data.Player.getInstance().getMaxBuildQueueSize();
					bqcur = c.buildQueue;
					bqcur = (bqcur != null) ? bqcur.length : 0;
					freeS = bqmax - bqcur;
					if (freeS == 0) return;
					
					buildingTypes = {
						"T":"|38|39|40|41|42|43|44|45|46|",
						"M":"|15|16|17|18|19|21|36|37|",
						"R":"|1|2|3|6|47|48|49|50|",
						"C":"|4|",
						"B":"|14|",
						"U":"|5|7|8|9|10|11|12|13|20|22|",
						"A":"|"+this.options.lowestLevelUpgradeIDs.join("|")+(this.options.lowestLevelUpgradeIDs[0] != "" ? "|1" : "")+(this.options.lowestLevelUpgradeIDs[1] != "" ? "|2" : "")+(this.options.lowestLevelUpgradeIDs[2] != "" ? "|3" : "")+(this.options.lowestLevelUpgradeIDs[5] != "" ? "|6" : "")+"|"
					};
					maxLvls = {
						"T":this.options.lowestLevelMax[0],
						"M":this.options.lowestLevelMax[1],
						"R":this.options.lowestLevelMax[2],
						"C":this.options.lowestLevelMax[3],
						"B":this.options.lowestLevelMax[4],
						"U":this.options.lowestLevelMax[5]
					}
					if (_type != "F") freeS = 1;
					if (_type == "F") _type = "A";
					_bTable = this.getValidBuildings(buildingTypes[_type]);
					ud = {"wl":tw, "sl":ts,"a":[]};
					for (j=0; j<freeS; j++) {
						_bTable.sort(function(a,b){return a[1]-b[1];});
						_bType = "";
						for (i=0; i<_bTable.length; i++) {
							if (_type == "A") {
								for (var b in buildingTypes) {
									if (b == "A") continue;
									if (buildingTypes[b].indexOf("|" + _bTable[i][2] + "|") != -1) _bType = b;
								}
								if (buildingTypes["A"].indexOf("|" + _bTable[i][2] + "|") != -1 && _bTable[i][1] >= maxLvls[_bType])
									continue;
								if (_bTable[i][2] == 23 && _bTable[i][1] >= 10)
									continue;
							}
							if (buildingTypes[_type].indexOf("|" + _bTable[i][2] + "|") != -1) {
								if (!_minis) {
									if (this.isAssignedToMinister(_bTable[i][0])) continue;
									wn = this.self(arguments).bd[_bTable[i][2]].w[_bTable[i][1]];
									sn = this.self(arguments).bd[_bTable[i][2]].s[_bTable[i][1]];
									if (wn > ud.wl || sn > ud.sl) continue;
									ud.wl -= wn;
									ud.sl -= sn;
								}
								ud.a.push([_bTable[i][0], _bTable[i][2], _minis]);
								_bTable[i][1] += 1;
								break;
							}
						}
					}
					for (i=0; i<ud.a.length; i++) {
						this.cityObject("UpgradeBuilding", ud.a[i][0], ud.a[i][1], 1, ud.a[i][2]);
					}
				},
				getValidBuildings: function(_ids) {
					c = webfrontend.data.City.getInstance();
					th = c.getTownhallLevel();
					this.getCity();
					_arr = new Array();
					_wallIn = false;
					for (k=0; k<this.city.length; k++) {
						if (_ids.indexOf("|" + this.city[k][2] + "|") != -1 && this.city[k][1] < 10 && this.city[k][1] > -1) {
							if ((_wallIn && this.city[k][2] == 23) || this.self(arguments).bd[this.city[k][2]].th > th)
								continue;
							_arr.push(this.city[k]);
							if (this.city[k][2] == 23)
								_wallIn = true;
						}
					}
					return _arr;
				},
				getCity: function() {
					if (LT.a.visMain.mapmode != "c") return;
					_cells = LT.a.visMain.cells;
					if (!_cells[0]) {
						window.setTimeout(function(){LT.main.getCity()}, 250);
						return;
					}
					_cgi = webfrontend.data.City.getInstance();
					waterCity = _cgi.getOnWater();

					_se = new Array();
					for (var _c in _cells) {
						_cell = _cells[_c].entities;
						for (var d in _cell) {
							if (_cell[d].basename != "CityWallLevel" && _cell[d].basename != "CityObject") {
								if (_cell[d].selectNode2 != null && _cell[d].selectNode3 != null) {
									if (_cell[d].selectNode.getY() < 880) {
										_se.push([_cell[d], _cell[d].selectNode2.getY()*256+_cell[d].selectNode2.getX()+1, _cell[d].visId]);
									} else {
										_se.push([_cell[d], _cell[d].selectNode3.getY()*256+_cell[d].selectNode3.getX()+1, _cell[d].visId]);
									}
									_se.push([_cell[d], _cell[d].selectNode.getY()*256+_cell[d].selectNode.getX(), _cell[d].visId]);
									_se.push([_cell[d], _cell[d].selectNode.getY()*256+_cell[d].selectNode.getX()+1, _cell[d].visId]);
									_se.push([_cell[d], _cell[d].selectNode2.getY()*256+_cell[d].selectNode2.getX(), _cell[d].visId]);
									_se.push([_cell[d], _cell[d].selectNode3.getY()*256+_cell[d].selectNode3.getX(), _cell[d].visId]);
								} else {
									if (_cell[d].getType) {
										if (_cell[d].getType() > 51 && _cell[d].getType() < 60) {
											_se.push([_cell[d], _cell[d].selectNode.getY()*256+_cell[d].selectNode.getX()+1, _cell[d].visId]);
											_se.push([_cell[d], _cell[d].selectNode.getY()*256+_cell[d].selectNode.getX()+2, _cell[d].visId]);
											_se.push([_cell[d], (_cell[d].selectNode.getY()+80)*256+_cell[d].selectNode.getX(), _cell[d].visId]);
											_se.push([_cell[d], (_cell[d].selectNode.getY()+80)*256+_cell[d].selectNode.getX()+1, _cell[d].visId]);
											_se.push([_cell[d], (_cell[d].selectNode.getY()+80)*256+_cell[d].selectNode.getX()+2, _cell[d].visId]);
											_se.push([_cell[d], (_cell[d].selectNode.getY()+160)*256+_cell[d].selectNode.getX(), _cell[d].visId]);
											_se.push([_cell[d], (_cell[d].selectNode.getY()+160)*256+_cell[d].selectNode.getX()+1, _cell[d].visId]);
											_se.push([_cell[d], (_cell[d].selectNode.getY()+160)*256+_cell[d].selectNode.getX()+2, _cell[d].visId]);
										}
									}
									_se.push([_cell[d], _cell[d].selectNode.getY()*256+_cell[d].selectNode.getX(), _cell[d].visId]);
								}
							}
						}
					}

					_se.sort(function(a,b){return a[1]-b[1];});

					this.city = new Array(441);
					_empty = [0, 1, 19, 20, 21, 41, 399, 419, 420, 421, 439, 440];
					_water = [352, 353, 373, 374, 375, 395, 396, 397, 398, 417, 418, 438];

					for (i=0; i<this.city.length; i++) this.city[i] = null;

					for (i=0; i<_empty.length; i++)	this.city[_empty[i]] = [-1, -1, -1]; // [buildingID/placeID, buildingLvl, buildingType]

					if (waterCity) {
						for (i=0; i<_water.length; i++) this.city[_water[i]] = [-1, -1, -2];
					}

					try {
						for (i=0, c=0; i<_se.length; i++) {
							while(this.city[c] != null) c++;
							if (_se[i][0].getResType != undefined)
								this.city[c] = [_se[i][0].getId(), 0, _se[i][0].getResType()+900]; // resource node
							else if (_se[i][0].getType != undefined) {
								if (_se[i][0].getLevel != undefined) // building
									this.city[c] = [_se[i][0].getId(), _se[i][0].getLevel()+LT.main.checkBuilding(_se[i][0].getId()), _se[i][0].getType()];
								else
									this.city[c] = [_se[i][0].getId(), _cgi.getWallLevel()+LT.main.checkBuilding("wall"), _se[i][0].getType()]; // wall
							} else if (_se[i][0].getPlaceId != undefined) {
								if (_se[i][0].drawNode != null) {
									if (_se[i][0].drawNode.image != undefined) {
										if (_se[i][0].drawNode.image.indexOf("tower") != -1) {
											this.city[c] = [_se[i][0].getPlaceId(), 0, 99]; // tower place
										} else {
											this.city[c] = [_se[i][0].getPlaceId(), 0, 98]; // empty, can be corn field
										}
									} else if (_se[i][0].drawNode.basename == "EffectNode") {
										this.city[c] = [_se[i][0].getPlaceId(), 0, 99]; // ??? bottom left tower in water city
									}
								} else {
									if (waterCity && /\b(331|332|351|354|372|376|394|416)\b/.test(c)) {
										this.city[c] = [_se[i][0].getPlaceId(), 0, 97]; // water building place
									} else {
										this.city[c] = [_se[i][0].getPlaceId(), 0, 98]; // empty
									}
								}
							}
						}

					for (i=0; i<this.city.length; i++) {
						if (this.city[i] == null) {
							this.city = new Array(441);
							window.setTimeout(function(){LT.main.getCity()}, 1000);
							return;
						}
					}

					LT.main.cityId = _cgi.getId();
					LT.city = this.city;
					} catch (e) { LT.debug(e); }
				},
				checkBuilding: function(_buildingId) {
					try {
						cBuildQueue = webfrontend.data.City.getInstance().getBuildQueue();
						d = 0;
						if (cBuildQueue != null) {
							for (j=0; j<cBuildQueue.length; j++) {
								if (cBuildQueue[j].building == _buildingId && (cBuildQueue[j].state == 2 || cBuildQueue[j].state == 5)) return -11; // single downgrade / full demolish
								if (cBuildQueue[j].building == _buildingId) d++;
								if (cBuildQueue[j].type == 23 && _buildingId == "wall") d++; // is city wall on queue?
							}
						}
					} catch(e) { LT.debug(e); }
					return d;
				},
				getIndex: function(_buildingId) {
					this.getCity();
					for (i=0; i<this.city.length; i++) {
						if (this.city[i][0] == _buildingId) return i;
					}
					return -1;
				},
				countUpgradeable: function() {
					if (this.app.visMain.getBuildings().length == 0) {
						window.setTimeout(function(){LT.main.countUpgradeable()}, 1500);
						return;
					}
					this.getCity();

					_upCount = 0;
					_wallLvl = 0;
					_palaceLvl = 0;
					for (i=0; i<this.city.length; i++) {
						if (this.city[i] == null) {
							this.getCity();
							window.setTimeout(function(){LT.main.countUpgradeable()}, 250);
							return;
						}
						if (this.city[i][1] > -1 && this.city[i][1] < 10 && !/\b(-1|-2|23|27|28|29|30|60|61|62|63|900|901|902|903|904|905|906|907|97|98|99)\b/.test(this.city[i][2]) && !(this.city[i][2] > 52 && this.city[i][2] < 60)) _upCount++;
						else if (this.city[i][2] == 23) _wallLvl = this.city[i][1];
						else if (this.city[i][2] > 51 && this.city[i][2] < 60) _palaceLvl = this.city[i][1];
					}
					if (_wallLvl < 10) _upCount++;
					if (_palaceLvl > 0 && _palaceLvl < 10) _upCount++;
					_cba = _cgi.getBuildingLimit() - _cgi.getBuildingCount();
					if (this.bQc.buildingSlotsTooltip.getLabel().indexOf("LT_cUp") == -1) {
						this.bQc.buildingSlotsValue.setValue(_cba + " (" + _upCount + ")");
						_ctxt = '</tr><tr><td id="LT_cUp">' + L("up_count_tt") + '</td><td>' + _upCount + '</td></tr></table>';
						_ttxt = LT.main.bQc.buildingSlotsTooltip.getLabel().replace("</tr></table>", _ctxt);
						this.bQc.buildingSlotsTooltip.setLabel(_ttxt);
					}
				},
				parseCoords: function() {
					tag = (this.lang != "de") ? "city" : "stadt";
					if (this.chat.chatLine.getValue() == null) this.chat.chatLine.setValue("");
					re = new RegExp("\\b(\\d{1,3}\\:\\d{1,3})(?!\\[\\\/" + tag + "\\])\\b", "g");
					if (this.chat.chatLine.getValue().match(re)) {
						this.chat.chatLine.setValue(this.chat.chatLine.getValue().replace(re, "[" + tag + "]$1[/" + tag + "]"));
						this.chat.chatLine.focus();
					} else {
						pos = this.chat.chatLine.getValue().length + tag.length + 3;
						this.chat.chatLine.setValue(this.chat.chatLine.getValue() + " " + "[" + tag + "][/" + tag + "]");
						this.chat.chatLine.focus();
						this.chat.chatLine.setTextSelection(pos, pos);
					}
				},
				parseText: function(txt) {
					if (this.lang == "de") {
						if (txt == "player") txt = "spieler";
						if (txt == "alliance") txt = "allianz";
					}
					
					if (this.chat.chatLine.getValue() == null) this.chat.chatLine.setValue("");
					cs = this.chat.chatLine.getTextSelection();
					ss = this.chat.chatLine.getTextSelectionStart();
					se = this.chat.chatLine.getTextSelectionEnd();
					if (cs != "") {
						this.chat.chatLine.setValue(this.chat.chatLine.getValue().substring(0, ss) + "[" + txt + "]" + cs + "[/" + txt + "]" + this.chat.chatLine.getValue().substring(se));
						this.chat.chatLine.focus();
					} else {
						pos = this.chat.chatLine.getValue().length + txt.length + 3;
						this.chat.chatLine.setValue(this.chat.chatLine.getValue() + " " + "[" + txt + "][/" + txt + "]");
						this.chat.chatLine.focus();
						this.chat.chatLine.setTextSelection(pos, pos);
					}
				},
				newConvertBBCode: function (D,E,F) {
					if (LT.options.cityTag == 1) {
						if (LT.main.getLang() != 1)
							D = D.replace(/\[city\]([0-9]*?)\:([0-9]*?)\[\/city\]/g, '<a href=# style="color: #1d79ff" onClick="qx.core.Init.getApplication().setMainView(\'r\', 0, $1*128, $2*80)">$1:$2</a>');
						if (LT.main.getLang() == 1)
							D = D.replace(/\[stadt\]([0-9]*?)\:([0-9]*?)\[\/stadt\]/g, '<a href=# style="color: #1d79ff" onClick="qx.core.Init.getApplication().setMainView(\'r\', 0, $1*128, $2*80)">$1:$2</a>');
					}
					D = LT.main.originalConvertBBCode(D,E,F);
					return D;
				},
				tweakInterface: function() {
					this.titleW.pointsLabel.setWidth(50);
					this.titleW.manaLabel.setLayoutProperties({left: 630});
					this.titleW.manaIcon.setLayoutProperties({left: 607})
					this.titleW.goldLabel.setWidth(110);
					this.bQc.sortButtonCont.setLayoutProperties({left: 200});
				},
				tweakReport: function() {
					children = this.app.getReportPage().reportBody.getChildren();
					if (children.length != 0 && typeof children[0].getValue != 'undefined') {
						if (qx.event.Registration.serializeListeners(children[0]).length != 0) return;
						children[0].addListener("click", function() {
							labValue = this.app.getReportPage().reportBody.getChildren()[0].getValue();
							reportId = labValue.match(/[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}/)[0];
							if (!reportId) return;
							if (this.chat.chatLine.getValue() == null) this.chat.chatLine.setValue("");
							this.chat.chatLine.setValue(this.chat.chatLine.getValue() + " " + "[report]" + reportId + "[/report]");
						}, this);
						children[0].addListener("disappear", function() {
							this.app.getReportPage().reportBody.addListenerOnce("addChildWidget", this.tweakReport, this);
						}, this);
						children[0].set({cursor: "pointer"});
					}
				},
				copyCoordsToChat: function(v) {
					posX = posY = 0;
					if (v == "c") {
						if (typeof this.cDetView.city.get_Coordinates == "undefined") {
							posX = this.cDetView.city.getPosX(); posY = this.cDetView.city.getPosY();
						} else {
							ctid = this.cDetView.city.get_Coordinates(); posX = ctid & 0xFFFF; posY = ctid >> 16;
						}
					}
					else if (v == "d") {
						if (typeof this.dDetView.city.get_Coordinates == "undefined") {
							posX = this.dDetView.city.getPosX(); posY = this.dDetView.city.getPosY();
						} else {
							did = this.dDetView.city.get_Coordinates(); posX = did & 0xFFFF; posY = did >> 16;
						}
					}
					else if (v == "n") { posX = this.ncView.cityPosX; posY = this.ncView.cityPosY; }
					//ctag = (this.lang != "de") ? "city" : "stadt";
					ctag = "coords";
					ccl = this.chat.chatLine.getValue();
					if (ccl == null) { this.chat.chatLine.setValue(""); ccl = ""; }
					if (posX >= 0 && posX <= 9) posX = "00" + posX;
					else if (posX > 9 && posX < 100) posX = "0" + posX;
					if (posY >= 0 && posY <= 9) posY = "00" + posY;
					else if (posY > 9 && posY < 100) posY = "0" + posY;
					this.chat.chatLine.setValue(ccl + " " + "[" + ctag + "]" + posX + ":" + posY + "[/" + ctag + "]");
				},
				showPurifyWindow: function() {
					if (webfrontend.data.City.getInstance().getCanPurifyResources()) {
						var g = this.app.getTradeWidget();
						g.setTab(5);
						this.app.switchOverlay(g);
						return;
					}
				},
				showOptimizationOverlay: function() {
					this.app.switchOverlay(this.OptimizationOverlay);
				},
				updateTopBottomButtons: function() {
					_j = this.bQc.getJobs();
					for (i=1; i<_j.length; i++) {
						if (_j[i].getUserData("Warnings") == 0) {
							if (i > 1) {
								bTop = _j[i].getUserData("top");
								bTop.set({width: 25, label: "T"});
								_j[i].getLayout()._getLayoutChildren()[0]._add(bTop, {left: 153, top: 26});
							}
							if (i >= 1 && i < _j.length-1) {
								bBottom = _j[i].getUserData("bottom");
								bBottom.set({width: 25, label: "B"});
								_j[i].getLayout()._getLayoutChildren()[0]._add(bBottom, {left: 238, top: 26});						
							}
							_j[i].getUserData("payButton").setLayoutProperties({left: 89, width: 16});
						}
					}
				},
				updateMiniMapButton: function() {
					if (typeof this.app.selectorBar.isMapSelectorBarAnchorToLeft != 'undefined') {
						if (!this.app.selectorBar.isMapSelectorBarAnchorToLeft()) {
							if (this.app.selectorBar.contNavigationRose.isVisible())
								this.miniMap.clientArea.setLayoutProperties({right:0, top: 260});
							else
								this.miniMap.clientArea.setLayoutProperties({right: 0, top: 133});
						} else {
							this.miniMap.clientArea.setLayoutProperties({right: 0, top: 62});
						}
					}
				},
				showGetUseButtons: function() {
					if (this.getUseCont1 == null) {
						this.cInfoView.palaceQuickUseStoneButton.getLayoutParent().setVisibility((this.cInfoView.palaceQuickUseStoneButton.getVisibility() == "excluded" ? "excluded" : this.getUseBtnVisibility));
						this.cInfoView.palaceQuickUseWoodButton.getLayoutParent().setVisibility((this.cInfoView.palaceQuickUseWoodButton.getVisibility() == "excluded" ? "excluded" : this.getUseBtnVisibility));
						this.cInfoView.quickUseBuildSpeedItemBtn.getLayoutParent().setVisibility((this.cInfoView.quickUseBuildSpeedItemBtn.getVisibility() == "excluded" ? "excluded" : this.getUseBtnVisibility));
						this.cInfoView.quickUseTownHallButton.getLayoutParent().setVisibility((this.cInfoView.quickUseTownHallButton.getVisibility() == "excluded" ? "excluded" : this.getUseBtnVisibility));
						this.cInfoView.quickUseBuildingItemBtn.getLayoutParent().setVisibility((this.cInfoView.quickUseBuildingItemBtn.getVisibility() == "excluded" ? "excluded" : this.getUseBtnVisibility));
						this.cInfoView.quickUseUnitQueueItemBtn.getLayoutParent().setVisibility((this.cInfoView.quickUseUnitQueueItemBtn.getVisibility() == "excluded" ? "excluded" : this.getUseBtnVisibility));
					} else {
						this.getUseCont1.getLayoutParent().setHeight((this.getUseBtnVisibility == "visible" ? 61 : 0));
						this.getUseCont2.getLayoutParent().setHeight((this.getUseBtnVisibility == "visible" ? 61 : 0));
						this.getUseCont3.getLayoutParent().setHeight((this.getUseBtnVisibility == "visible" ? 61 : 0));
					}
				},
				switchGetUseDisplay: function() {
					if (this.getUseCont1 == null) {
						if (LT.options.hideGetUseBtn) {
							this.getUseBtnVisibility = "excluded";
							this.app.getUserData("showGetUseBtn").setVisibility("visible");
							this.cInfoView.palaceQuickUseStoneButton.getLayoutParent().setVisibility("excluded");
							this.cInfoView.palaceQuickUseWoodButton.getLayoutParent().setVisibility("excluded");
							this.cInfoView.quickUseBuildSpeedItemBtn.getLayoutParent().setVisibility("excluded");
							this.cInfoView.quickUseTownHallButton.getLayoutParent().setVisibility("excluded");
							this.cInfoView.quickUseBuildingItemBtn.getLayoutParent().setVisibility("excluded");
							this.cInfoView.quickUseUnitQueueItemBtn.getLayoutParent().setVisibility("excluded");
						} else {
							this.getUseBtnVisibility = "visible";
							this.app.getUserData("showGetUseBtn").setVisibility("excluded");
							this.cInfoView.palaceQuickUseStoneButton.getLayoutParent().setVisibility("visible");
							this.cInfoView.palaceQuickUseWoodButton.getLayoutParent().setVisibility("visible");
							this.cInfoView.quickUseBuildSpeedItemBtn.getLayoutParent().setVisibility("visible");
							this.cInfoView.quickUseTownHallButton.getLayoutParent().setVisibility("visible");
							this.cInfoView.quickUseBuildingItemBtn.getLayoutParent().setVisibility("visible");
							this.cInfoView.quickUseUnitQueueItemBtn.getLayoutParent().setVisibility("visible");
						}
					} else {
						if (LT.options.hideGetUseBtn) {
							this.app.getUserData("showGetUseBtn").setVisibility("visible");
							if (this.getUseCont1 != null) {
								this.getUseCont1.getLayoutParent().setHeight(0);
								this.getUseCont2.getLayoutParent().setHeight(0);
								this.getUseCont3.getLayoutParent().setHeight(0);
							}
						} else {
							this.app.getUserData("showGetUseBtn").setVisibility("excluded");
							if (this.getUseCont1 != null) {
								this.getUseCont1.getLayoutParent().setHeight(61);
								this.getUseCont2.getLayoutParent().setHeight(61);
								this.getUseCont3.getLayoutParent().setHeight(61);
							}
						}
					}
				},
				showOptimizeButtons: function() {
					if (this.getOptimize == null) {
						btn = new qx.ui.form.Button(null, "webfrontend/theme/scrollbar/scrollbar-up.png");
						btn.set({width: 30, height: 20, appearance: "button-brown-sort", toolTipText: L("btn_trade_hide")});
						btn.addListener("click", function() {
							if (LT.main.cTradeInfoView._getChildren()[2].getVisibility() == "visible") {
								LT.main.cTradeInfoView._getChildren()[2].setVisibility("excluded");
								this.set({toolTipText: L("btn_trade_show"), icon: "webfrontend/theme/scrollbar/scrollbar-down.png"});
							} else {
								LT.main.cTradeInfoView._getChildren()[2].setVisibility('visible');
								this.set({toolTipText: L("btn_trade_hide"), icon: "webfrontend/theme/scrollbar/scrollbar-up.png"});
							}
						}, btn);
						LT.main.cTradeInfoView._getChildren()[0].add(btn, {top: 7, left: 140});
					} else {
						btn = new qx.ui.form.Button(null, "webfrontend/theme/scrollbar/scrollbar-up.png");
						btn.set({width: 30, height: 20, appearance: "button-brown-sort", toolTipText: L("btn_trade_hide")});
						btn.addListener("click", function() {
							if (LT.main.cTradeInfoView._getChildren()[2].getVisibility() == "visible") {
								LT.main.cTradeInfoView._getChildren()[2].setVisibility("excluded");
								this.set({toolTipText: L("btn_trade_show"), icon: "webfrontend/theme/scrollbar/scrollbar-down.png"});
							} else {
								LT.main.cTradeInfoView._getChildren()[2].setVisibility('visible');
								this.set({toolTipText: L("btn_trade_hide"), icon: "webfrontend/theme/scrollbar/scrollbar-up.png"});
							}
						}, btn);
						LT.main.cTradeInfoView._getChildren()[0].add(btn, {top: 7, left: 140});
					}
				},
				switchOptimizeDisplay: function() {
					if (this.getOptimize == null) {
						if (LT.options.hideOptimizeBtn) {
							this.getOptimizeVisibility = "excluded";
							this.app.getUserData("showOptimizeBtn").setVisibility("visible");
							//this.cInfoView.palaceQuickUseStoneButton.getLayoutParent().setVisibility("excluded");
						} else {
							this.getOptimizeVisibility = "visible";
							this.app.getUserData("showOptimizeBtn").setVisibility("excluded");
							//this.cInfoView.palaceQuickUseStoneButton.getLayoutParent().setVisibility("visible");
						}
					} else {
						if (LT.options.hideOptimizeBtn) {
							this.app.getUserData("showOptimizeBtn").setVisibility("visible");
							if (this.getOptimize != null) {
								this.getOptimize.getLayoutParent().setHeight(0);
							}
						} else {
							this.app.getUserData("showOptimizeBtn").setVisibility("excluded");
							if (this.getOptimize != null) {
								this.getOptimize.getLayoutParent().setHeight(61);
							}
						}
					}
				},
				createTradeButtons: function() {
					if (this.app.tradeWidget) {
						_pageSend = null;
						for (var o in LT.a.tradeWidget) {
							if (LT.a.tradeWidget[o] != null && /SendResourcesPage/.test(LT.a.tradeWidget[o].basename))
								_pageSend = LT.a.tradeWidget[o];
							if (LT.a.tradeWidget[o] != null && /RequestResourcesPage/.test(LT.a.tradeWidget[o].basename))
								_prr = LT.a.tradeWidget[o];
						}
						if (_pageSend == null) return;
						_pageSendCont = _pageSend.aResValueSpinner[0].getLayoutParent(); // spinners container
						_tbd = [
							["1k", 1], ["5k", 5], ["10k", 10], ["25k", 25],
							["50k", 50], ["100k", 100], ["250k", 250], ["500k", 500]
						];
						_pageSendCont.getLayout().setSpacingX(5);
						for (i=0; i<4; i++) {
							for (j=0; j<8; j++) {
								tb = new qx.ui.form.Button(_tbd[j][0]).set({appearance: "button-recruiting", font: "bold"});
									tb.addListener("click", this.increaseResAmount, {am:_tbd[j][1], r:i, p:_pageSend});
								_pageSendCont.add(tb, {column: j+3, row: i+1});
							}
						}

						// add listeners to spinners in request resources page
						_prrTable = null;
						_spObj = null;
						_prrSel = null;
						for (var p in _prr) {
							if (_prr[p] != null) {
								if (_prr[p].toString().indexOf("SpinnerInt") != -1 && _prr[p].toString().indexOf("9999999") != -1) {
									re = /([_a-zA-z]+)(?=\s*=\s*\(?new\s*\(?webfrontend\.g?ui\.SpinnerInt)/g;
									_spObj = _prr[p].toString().match(re);
								}
								if (_prr[p].toString().indexOf("SimpleColFormattingDataModel") != -1) {
									_prrTable = _prr[p];
								}
								if (_prr[p].toString().indexOf("SelectBox") != -1) {
									_prrSel = _prr[p];
								}
							}
						}
						cb = new qx.ui.form.CheckBox(L("trade_limit"));
						if (LT.options.resLimit)
							cb.setValue(true);
						cb.addListener("appear", function() { this.setValue(LT.options.resLimit); }, cb);
						_prr[_spObj[0]].getLayoutParent().add(cb, {row:2, column:0});
						LT.main.temp_limit = cb;
						_prrSel.addListener("changeSelection", function() { if (this.getSelectables()[1] == this.getSelection()[0]) {LT.main.temp_limit.setValue(false);} else {LT.main.temp_limit.setValue(LT.options.resLimit);}}, _prrSel);
						_prrSel.addListener("appear", function() { if (this.t.getData().length > 0 && this.t.getData()[0].originalData.resType > 2) this.s.setSelection([this.s.getChildren()[0]]); if (this.s.getSelectables()[1] == this.s.getSelection()[0]) {LT.main.temp_limit.setValue(false);} else {LT.main.temp_limit.setValue(LT.options.resLimit);}}, {t:_prrTable, s:_prrSel});
						
						_prr[_spObj[0]].addListener("changeValue", this.limitResources, {t:_prrTable, s:_prr[_spObj[0]], b:0});
						_prr[_spObj[1]].addListener("changeValue", this.limitResources, {t:_prrTable, s:_prr[_spObj[1]], b:1});

						webfrontend.base.Timer.getInstance().removeListenerById(this.tradeButtonsListener);
					}
				},
				increaseResAmount: function() {
					curVal = this.p.aResValueSpinner[this.r].getValue();
					this.p.aResValueSpinner[this.r].setValue(curVal + this.am*1000);
				},
				limitResources: function() {
					if (!LT.main.temp_limit.getValue()) return;
					c = webfrontend.data.City.getInstance();
					_it = c.tradeIncoming;
					if (_it == null || _it == undefined) _it = [];
					_data = this.t.getData();
					for (i=0; i<_data.length; i++) {
						if (_data[i][0] == true) {
							_res = _data[i].originalData.resType; // resource type
							_inc = 0;
							// incoming trade
							for (k=0; k<_it.length; k++) {
								for (j=0; j<_it[k].resources.length; j++) {
									if (_it[k].resources[j].type == _res) 
										_inc += _it[k].resources[j].count;
								}
							}
					
							_timeSpan = (this.b == 0) ? _data[i].originalData.tl : _data[i].originalData.ts;
							if (_res == 4) {
								_fc = Math.round(c.getFoodConsumption() * 3600);
								_fcs = Math.round(c.getFoodConsumptionSupporter() * 3600);
								_ft = c.getResourceGrowPerHour(4) - _fc - _fcs;
							}
							curVal = c.getResourceCount(_res);
							curDel = c.resources[_res].delta;
							curMax = c.getResourceMaxStorage(_res);

							_val = Math.floor(curMax - (curVal + ((_res == 4) ? _ft*_timeSpan/3600 : _timeSpan * curDel)) - _inc);
							if (_val < 0) _val = 0;

							if (this.s.getValue() > _val) {
								this.s.setValue(_val);
							}
						}
					}
				},
				showOptionsPage: function() {
					this.app.switchOverlay(this.optionsPage);
				},
				loadOptions: function() {
					forceSave = false;
					_str = localStorage.getItem("LT_options");
					if (_str)
						this.options = qx.lang.Json.parse(_str);
					else {
						this.options = {
							"thousandsSeparator": 0,
							"hotkeys": {
								"build": {
									"woodcutter": "W",
									"quarry": "Q",
									"farm": "F",
									"cottage": "C",
									"market": "P",
									"ironmine": "I",
									"sawmill": "L",
									"mill": "M",
									"hideout": "H",
									"stonemason": "A",
									"foundry": "D",
									"townhouse": "U",
									"barracks": "B",
									"cityguardhouse": "K",
									"trainingground": "G",
									"stable": "E",
									"workshop": "Y",
									"shipyard": "V",
									"warehouse": "S",
									"castle": "X",
									"harbor": "R",
									"moonglowtower": "J",
									"trinsictemple": "Z",
									"lookouttower": "1",
									"ballistatower": "2",
									"guardiantower": "3",
									"rangertower": "4",
									"templartower": "5",
									"pitfalltrap": "6",
									"barricade": "7",
									"arcanetrap": "8",
									"camouflagetrap": "9"
								},
								"upgrades": {
									"upgrade": "U",
									"downgrade": "D",
									"minister": "A"
								},
								"global": {
									"prevcity": "[",
									"nextcity": "]"
								}
							},
							"lowestLevelUpgradeIDs": [47,48,50,4,5,49,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,36,37,38,39,40,41,42,43,44,45,46,12,23],
							"lowestLevelMax": [10,10,10,10,10,10],
							"switchToAllyTab": false,
							"showIncResCont": 1,
							"showQueueTimes": true,
							"showOptimizationOverlay": false,
							"incResClrs": ["#FF0000","#F7941D","#FFE400","#40C849"],
							"chatColors": ["#fcbf8f", "#78b042", "#000000", "#ff4076", "#fa9bb6", "#aaaaaa", "#b0843f"],
							"chatMaxLines": 100,
							"chatOpacity": 55,
							"cityTag": 0,
							"resLimit": true,
							"userLang": "",
							"showMiniMap": true,
							"miniMapColors": [ "#00C0FF", "#0000FF", "#00FF80", "#468246", "#E0E060", "#969640", "#FF8080", "#FF0000", "#00C8C8", "#008080", "#8C4600", "#643200", "#C0C0C0", "#737373", "#FFFFFF", "#000000", "#FFFFFF", "#000000" ],
							"miniMapMark": [ 3, 3, 3, 3, 3, 3, 3, 1, 1 ],
							"saveSsCn": false,
							"tradeLabelsAmount": 999,
							"hideGetUseBtn": false,
							"hideOptimizeBtn": false,
							"LTver": LTversion
						};
					}
					//1.3.2
					if (this.options.lowestLevelUpgradeIDs[0] == 1) this.options.lowestLevelUpgradeIDs[0] = 47;
					if (this.options.lowestLevelUpgradeIDs[1] == 2) this.options.lowestLevelUpgradeIDs[1] = 48;
					if (this.options.lowestLevelUpgradeIDs[2] == 3) this.options.lowestLevelUpgradeIDs[2] = 50;
					if (this.options.lowestLevelUpgradeIDs[5] == 6) this.options.lowestLevelUpgradeIDs[5] = 49;
					//
					//1.3.7
					if (!this.options.hasOwnProperty("showMiniMap")) this.options.showMiniMap = true;
					if (!this.options.hasOwnProperty("miniMapColors")) this.options.miniMapColors = [ "#00C0FF", "#0000FF", "#00FF80", "#468246", "#E0E060", "#969640", "#FF8080", "#FF0000", "#00C8C8", "#008080", "#8C4600", "#643200", "#C0C0C0", "#737373", "#FFFFFF", "#000000", "#FFFFFF", "#000000" ];
					if (!this.options.hasOwnProperty("miniMapMark")) this.options.miniMapMark = [ 3, 3, 3, 3, 3, 3, 3, 1, 1 ];
					//1.3.8
					if (this.options.miniMapColors.length == 8) this.options.miniMapColors = [ "#00C0FF", "#0000FF", "#00FF80", "#468246", "#E0E060", "#969640", "#FF8080", "#FF0000", "#00C8C8", "#008080", "#8C4600", "#643200", "#C0C0C0", "#737373", "#FFFFFF", "#000000", "#FFFFFF", "#000000" ];
					if (this.options.miniMapMark.length == 8) this.options.miniMapMark = [ 3, 3, 3, 3, 3, 3, 3, 1, 1 ];
					//1.3.9
					if (/false|true/.test(this.options.miniMapMark.join(""))) this.options.miniMapMark = [ 3, 3, 3, 3, 3, 3, 3, 1, 1 ];
					//1.4.7
					if (!this.options.hasOwnProperty("saveSsCn")) this.options.saveSsCn = false;
					//1.5.1
					if (this.options.chatColors.length == 5) this.options.chatColors.push("#bd0000");
					if (!this.options.hasOwnProperty("tradeLabelsAmount")) this.options.tradeLabelsAmount = 999;
					if (!this.options.hasOwnProperty("hideGetUseBtn")) this.options.hideGetUseBtn = false;

					//1.5.8
					if (this.options.hasOwnProperty("LTver") && parseInt(this.options.LTver.replace(/\./g, "")) < 158) {
						this.options.LTver = LTversion;
						if (this.options.chatColors.length < 7) {
							this.options.chatColors[5] = "#aaaaaa";
							this.options.chatColors.push("#b0843f");
						}
						forceSave = true;
					}
					
					this.app.setUserData("LT_options", this.options);
					if (forceSave) {
						str = qx.lang.Json.stringify(this.options);
						localStorage.setItem("LT_options", str);
					}
				},
				getLang: function() {
					return this.langToId(this.lang);
				},
				setLang: function(l) {
					this.lang = l;
					//qx.locale.Manager.getInstance().setLocale(l);
				},
				langToId: function(l) {
					switch(l) {
						case "en":
							return 0;
						case "de":
							return 1;
						case "es":
							return 2;
						case "pl":
							return 3;
						case "pt":
						case "pt_BR":
							return 4;
						case "ru":
							return 5;
						case "it":
							return 6;
						case "fr":
							return 7;
						default:
							return 0;
					}
				},
				thSep: function(val) {
					if (val == undefined) return "";
					separators = [".", ",", " ", ""];
					return val.toString().replace(/\d(?=(\d{3})+(\D|$))/g, "$&" + separators[LT.options.thousandsSeparator]);
				},
				debug: function(s) {
					if (typeof console != 'undefined') console.log(s);
					else if (window.opera) opera.postError(s);
					else GM_log(s);
				}
			}
		});
		qx.Class.define("louTweak.queueTimesLabel", {
			extend: qx.core.Object,
			construct: function () {
				this.queueTimeCont = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.queueTimeContBgr = new qx.ui.basic.Image("");
				this.queueTimeContBgr.setWidth(280);
				this.queueTimeContBgr.setHeight(50);
				this.queueTimeCont.add(this.queueTimeContBgr, {left: 0, top: 0});
				gr = new qx.ui.layout.Grid(3, 4);
				gr.setColumnMaxWidth(0, 20);
				gr.setColumnMinWidth(1, 200);
				gr.setColumnMaxWidth(2, 40);
				this.queueTimeGrid = new qx.ui.container.Composite(gr);
				this.queueTimeCont.add(this.queueTimeGrid, {left: 8, top: 8});
				this.queueTimeGrid.add(new qx.ui.basic.Label("BQ:").set({textColor: "text-gold", font: "bold"}), {column:0, row:0});
				this.queueTimeGrid.add(new qx.ui.basic.Label("UQ:").set({textColor: "text-gold", font: "bold"}), {column:0, row:1});
				this.buildQueueTimeLabel = new qx.ui.basic.Label("").set({textColor: "text-gold", font: "bold"});
				this.buildQueueSlotsLabel = new qx.ui.basic.Label("").set({textColor: "text-gold", font: "bold"});
				this.unitQueueTimeLabel = new qx.ui.basic.Label("").set({textColor: "text-gold", font: "bold"});
				this.unitQueueSlotsLabel = new qx.ui.basic.Label("").set({textColor: "text-gold", font: "bold"});
				this.queueTimeGrid.add(this.buildQueueTimeLabel, {column:1, row:0});
				this.queueTimeGrid.add(this.buildQueueSlotsLabel, {column:2, row:0});
				this.queueTimeGrid.add(this.unitQueueTimeLabel, {column:1, row:1});
				this.queueTimeGrid.add(this.unitQueueSlotsLabel, {column:2, row:1});
				
				webfrontend.base.Timer.getInstance().addListener("uiTick", this.updateQueueTimes, this);
			},
			members: {
				queueTimeCont: null,
				queueTimeContBgr: null,
				queueTimeGrid: null,
				buildQueueTimeLabel: null,
				buildQueueSlotsLabel: null,
				unitQueueTimeLabel: null,
				unitQueueSlotsLabel: null,
				updateQueueTimes: function() {
					if (LT.options.showQueueTimes)
						this.queueTimeCont.setVisibility("visible");
					else
						this.queueTimeCont.setVisibility("excluded");
					
					if (typeof LT.a.selectorBar.isMapSelectorBarAnchorToLeft != 'undefined') {
						if (LT.a.selectorBar.isMapSelectorBarAnchorToLeft()) {
							if (LT.a.selectorBar.contNavigationRose.isVisible())
								this.queueTimeCont.setLayoutProperties({left: 690, top: 65});
							else
								this.queueTimeCont.setLayoutProperties({left: 405, top: 135});
						} else {
							this.queueTimeCont.setLayoutProperties({left: 405, top: 65});
						}
					}

					p = webfrontend.data.Player.getInstance();
					b = webfrontend.data.City.getInstance().buildQueue;
					u = webfrontend.data.City.getInstance().unitQueue;
					st = webfrontend.data.ServerTime.getInstance();
					if (b != null) {
						timeSpan = b[b.length-1].end - st.getServerStep();
						endTime = webfrontend.Util.getDateTimeString(st.getStepTime(b[b.length-1].end));
						if (timeSpan < 0)
							this.buildQueueTimeLabel.setValue("0:00");
						else
							this.buildQueueTimeLabel.setValue(endTime + " (" + webfrontend.Util.getTimespanString(timeSpan) + ")");
						this.buildQueueSlotsLabel.setValue(b.length + " / " + p.getMaxBuildQueueSize());
					} else {
						this.buildQueueTimeLabel.setValue("0:00");
						this.buildQueueSlotsLabel.setValue("0" + " / " + p.getMaxBuildQueueSize());
					}
					if (u != null) {
						timeSpan = u[u.length-1].end - st.getServerStep();
						endTime = webfrontend.Util.getDateTimeString(st.getStepTime(u[u.length-1].end));
						if (timeSpan < 0)
							this.unitQueueTimeLabel.setValue("0:00");
						else
							this.unitQueueTimeLabel.setValue(endTime + " (" + webfrontend.Util.getTimespanString(timeSpan) + ")");
						this.unitQueueSlotsLabel.setValue(u.length + " / " + p.getMaxUnitQueueSize());
					} else {
						this.unitQueueTimeLabel.setValue("0:00");
						this.unitQueueSlotsLabel.setValue("0" + " / " + p.getMaxUnitQueueSize());
					}
				}
			}
		});
		qx.Class.define("louTweak.OptimizationOverlay", {
			extend: webfrontend.gui.OverlayWidget,
			construct: function() {
				webfrontend.gui.OverlayWidget.call(this);

				this.clientArea.setLayout(new qx.ui.layout.Canvas());
				this.setTitle("Optimization");
				this.tabView = new qx.ui.tabview.TabView().set({contentPaddingLeft: 15, contentPaddingRight: 10, contentPaddingTop: 10, contentPaddingBottom: 10});
				this.tabPages = [
					{name:"City", page:null, vbox:null},
					{name:"Empire", page:null, vbox:null},
					{name:"Goals", page:null, vbox:null}
				];
				for (i=0; i<this.tabPages.length; i++) {
					page = new qx.ui.tabview.Page(this.tabPages[i].name);
					page.setLayout(new qx.ui.layout.Canvas());
					vbox = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
					scroll = new qx.ui.container.Scroll(vbox);
					page.add(scroll, {top: 0, left: 0, right: 0, bottom: 0});
					this.tabPages[i].vbox = vbox;
					this.tabPages[i].page = page;
				}
				
				// ----- Page 1

				// ----- Chat max lines / transparency
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("Wood")).set({paddingTop: 4});
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				sp = new webfrontend.ui.SpinnerInt(10, LT.options.chatMaxLines, 100);
				sp.getChildControl("textfield").setLiveUpdate(true);
				sp.getChildControl("textfield").addListener("changeValue", function() { _val = parseInt(this.getValue()); LT.options.chatMaxLines = _val; webfrontend.config.Config.getInstance().getChat().setMaxLines(_val); }, sp);
				LT.a.setElementModalInput(sp);
				cont.add(sp);

				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_chat_opacity")).set({paddingTop: 4});
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				sp = new webfrontend.ui.SpinnerInt(0, (100-parseInt(LT.options.chatOpacity)), 100);
				sp.getChildControl("textfield").setLiveUpdate(true);
				sp.getChildControl("textfield").addListener("changeValue", function() { _val = parseInt(this.getValue()); LT.options.chatOpacity = 100 - _val; LT.a.chat.BgrLabel.setOpacity((100-_val)/100); }, sp);
				LT.a.setElementModalInput(sp);
				cont.add(sp);
				this.tabPages[0].vbox.add(cont);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- Hide 'Optimization' buttons
				cb = new qx.ui.form.CheckBox(L("opts_hide_optimize"));
				if (LT.options.hideOptimizeBtn) {
					cb.setValue(true);
					LT.main.switchOptimizeDisplay();
				}
				cb.addListener("click", function() { LT.options.hideOptimizeBtn = this.getValue() ? true : false; LT.main.switchOptimizeDisplay(); }, cb);
				this.tabPages[0].vbox.add(cb);
				
				// ----- Hide 'Get & Use' buttons
				cb = new qx.ui.form.CheckBox(L("opts_hide_get_use"));
				if (LT.options.hideGetUseBtn) {
					cb.setValue(true);
					LT.main.switchGetUseDisplay();
				}
				cb.addListener("click", function() { LT.options.hideGetUseBtn = this.getValue() ? true : false; LT.main.switchGetUseDisplay(); }, cb);
				this.tabPages[0].vbox.add(cb);
				
				// ----- Show queue info window
				cb = new qx.ui.form.CheckBox(L("opts_show_queue_win"));
				if (LT.options.showQueueTimes)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.showQueueTimes = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);
				
				// ----- Save overlay layout in city notes
				cb = new qx.ui.form.CheckBox(L("opts_save_ss_cn"));
				if (LT.options.saveSsCn)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.saveSsCn = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);

				// ----- Requested resources limit
				cb = new qx.ui.form.CheckBox(L("opts_limit_req_res"));
				if (LT.options.resLimit)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.resLimit = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- Incoming resources label
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_inc_res").lab);
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ L("opts_inc_res").disabled, L("opts_inc_res").always, L("opts_inc_res").context ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(rbs[i]);
					rb.setUserData("id", i);
					rb.setGroup(rg);
					cont.add(rb);
					cont.add(new qx.ui.core.Spacer(10));
				}
				
				rg.setSelection([rg.getChildren()[LT.options.showIncResCont]]);
				rg.addListener("changeSelection", function() { LT.options.showIncResCont = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);
				
				// ----- Thousands separator
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_separator").lab);
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ L("opts_separator").period, L("opts_separator").comma, L("opts_separator").space, L("opts_separator").none ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(rbs[i]);
					rb.setUserData("id", i);
					rb.setGroup(rg);
					cont.add(rb);
					cont.add(new qx.ui.core.Spacer(10));				
				}
			
				rg.setSelection([rg.getChildren()[LT.options.thousandsSeparator]]);
				rg.addListener("changeSelection", function() { LT.options.thousandsSeparator = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);

				// ----- City tag
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_city_tag").lab);
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ L("opts_city_tag").info, L("opts_city_tag").region ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(rbs[i]);
					rb.setUserData("id", i);
					rb.setGroup(rg);
					cont.add(rb);
					cont.add(new qx.ui.core.Spacer(10));				
				}

				rg.setSelection([rg.getChildren()[LT.options.cityTag]]);
				rg.addListener("changeSelection", function() { LT.options.cityTag = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);

				// ----- LoU Tweak language
				gr = new qx.ui.layout.Grid(0, 5);
				gr.setColumnMinWidth(0, 120);
				gr.setColumnMinWidth(1, 120);
				gr.setColumnMinWidth(2, 120);
				gr.setColumnMinWidth(3, 120);
				cont = new qx.ui.container.Composite(gr).set({marginLeft: 20});
				lab = new qx.ui.basic.Label(L("opts_lang").lab + " " + L("req_restart") + ":").set({marginLeft: 20});
				this.tabPages[0].vbox.add(lab);
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ "en", "de", "es", "pl", "pt", "ru", "it", "fr" ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(L("opts_lang")[rbs[i]]);
					rb.setUserData("id", rbs[i]);
					rb.setGroup(rg);
					cont.add(rb, {row: Math.floor(i/4), column: i%4});
				}

				rg.setSelection([rg.getChildren()[LT.main.langToId(LT.options.userLang)]]);
				rg.addListener("changeSelection", function() { LT.options.userLang = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- MiniMap
				gr = new qx.ui.layout.Grid(0, 9);
				gr.setColumnMinWidth(0, 80);
				gr.setColumnMinWidth(1, 60);
				gr.setColumnMinWidth(2, 60);
				gr.setColumnMinWidth(3, 60);
				gr.setColumnMinWidth(4, 60);
				gr.setColumnAlign(0, "right", "middle");
				gr.setColumnAlign(1, "center", "middle");
				gr.setColumnAlign(2, "center", "middle");
				gr.setColumnAlign(3, "center", "middle");
				gr.setColumnAlign(4, "center", "middle");
				cgb = new qx.ui.container.Composite(gr).set({marginLeft: 20});
				this.setUserData("mmcb", cgb);
				//cgb.setVisibility("excluded");
				
				cb = new qx.ui.form.CheckBox(L("opts_minimap").enable_lab);
					if (LT.options.showMiniMap) {
						cb.setValue(true);
						this.getUserData("mmcb").setVisibility("visible");
					}
				cb.addListener("click", function() {
					LT.options.showMiniMap = this.getValue() ? true : false;
					LT.main.optionsPage.getUserData("mmcb").setVisibility((this.getValue() ? "visible" : "excluded"));
					LT.main.miniMap.clientArea.setVisibility((this.getValue() ? "visible" : "excluded"));
				}, cb);
						
				this.tabPages[0].vbox.add(cb);
				
				cbs = [
					[L("opts_minimap").show_cities, 0, 0],
					[L("opts_minimap").show_none, 0, 1],
					[L("opts_minimap").show_noncastle, 0, 2],
					[L("opts_minimap").show_castle, 0, 3],
					[L("opts_minimap").show_all, 0, 4],
					[L("opts_minimap").show_self, 1, 0],
					[L("opts_minimap").show_alliance, 2, 0],
					[L("opts_minimap").show_allied, 3, 0],
					[L("opts_minimap").show_enemy, 4, 0],
					[L("opts_minimap").show_nap, 5, 0],
					[L("opts_minimap").show_other, 6, 0],
					[L("opts_minimap").show_lawless, 7, 0]
				];
				for (i=0; i<cbs.length; i++) {
					lab = new qx.ui.basic.Label(cbs[i][0]);
					cgb.add(lab, {row:cbs[i][1], column:cbs[i][2]});
				}
				lab = new qx.ui.basic.Label(L("opts_minimap").show_moongate);
				cgb.add(lab, {row:9, column:0});
				lab = new qx.ui.basic.Label(L("opts_minimap").show_shrine);
				cgb.add(lab, {row:10, column:0});
				
				for (j=0; j<7; j++) {
					rg = new qx.ui.form.RadioGroup();
					for (i=0; i<4; i++) {
						rb = new qx.ui.form.RadioButton(null);
						rb.setUserData("id", i);
						rb.setGroup(rg);
						cgb.add(rb, {row:j+1, column:i+1});
					}
					rg.setSelection([rg.getChildren()[LT.options.miniMapMark[j]]]);
					rg.addListener("changeSelection", function() { LT.options.miniMapMark[this.it] = this.g.getSelection()[0].getUserData("id"); }, {g:rg, it:j});
				}
				rg = new qx.ui.form.RadioGroup();
				rb = new qx.ui.form.RadioButton(L("no")); rb.setUserData("id", 0); rb.setGroup(rg); cgb.add(rb, {row:9, column:1});
				rb = new qx.ui.form.RadioButton(L("yes")); rb.setUserData("id", 1); rb.setGroup(rg); cgb.add(rb, {row:9, column:2});
				rg.setSelection([rg.getChildren()[LT.options.miniMapMark[7]]]);
				rg.addListener("changeSelection", function() { LT.options.miniMapMark[7] = this.getSelection()[0].getUserData("id"); }, rg);
				rg = new qx.ui.form.RadioGroup();
				rb = new qx.ui.form.RadioButton(L("no")); rb.setUserData("id", 0); rb.setGroup(rg); cgb.add(rb, {row:10, column:1});
				rb = new qx.ui.form.RadioButton(L("yes")); rb.setUserData("id", 1); rb.setGroup(rg); cgb.add(rb, {row:10, column:2});
				rg.setSelection([rg.getChildren()[LT.options.miniMapMark[8]]]);
				rg.addListener("changeSelection", function() { LT.options.miniMapMark[8] = this.getSelection()[0].getUserData("id"); }, rg);

				if (!LT.options.showMiniMap) {
					this.getUserData("mmcb").setVisibility("excluded");
				}
				this.tabPages[0].vbox.add(cgb);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- Lowest level upgrades
				gr = new qx.ui.layout.Grid(0, 9);
				gr.setColumnMinWidth(0, 130);
				gr.setColumnMinWidth(1, 130);
				gr.setColumnMinWidth(2, 130);
				gr.setColumnMinWidth(3, 130);
				cont = new qx.ui.container.Composite(gr);
				
				lab = new qx.ui.basic.Label(L("opts_lowest_lvl").lab1);
				this.tabPages[0].vbox.add(lab);
				
				_bids = [47,48,50,4,5,49,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,36,37,38,39,40,41,42,43,44,45,46,12,23];
				mb = webfrontend.res.Main.getInstance().buildings;
				for (i=0; i<34; i++) {
					cb = new qx.ui.form.CheckBox(mb[_bids[i]].dn);
					if (LT.options.lowestLevelUpgradeIDs[i] != "")
						cb.setValue(true);
					cb.addListener("click", function() { LT.options.lowestLevelUpgradeIDs[this.i] = this.c.getValue() ? this.b : ""; }, {c:cb, b:_bids[i], i:i});
					cont.add(cb, {column: i%4, row: Math.floor(i/4)});
				}			
				this.tabPages[0].vbox.add(cont);				
				
				// ----- Level limits
				lab = new qx.ui.basic.Label(L("opts_lowest_lvl").lab2);
				this.tabPages[0].vbox.add(lab);
				
				gr = new qx.ui.layout.Grid(4, 4);
				gr.setColumnMinWidth(0, 60);
				gr.setColumnMinWidth(2, 60);
				gr.setColumnAlign(0, "right", "middle");
				gr.setColumnAlign(2, "right", "middle");
				cont = new qx.ui.container.Composite(gr);
				bTypesLabels = [ L("opts_lowest_lvl").towers, L("opts_lowest_lvl").military, L("opts_lowest_lvl").resource, L("opts_lowest_lvl").cottage, L("opts_lowest_lvl").barracks, L("opts_lowest_lvl").utilities ];
				for (i=0; i<6; i++) {
					lab = new qx.ui.basic.Label(bTypesLabels[i]);
					cont.add(lab, {row: Math.floor(i/2), column: ((i%2 == 0) ? 0 : 2)});
					sp = new webfrontend.ui.SpinnerInt(0, LT.options.lowestLevelMax[i], 10);
					sp.getChildControl("textfield").setLiveUpdate(true);
					sp.getChildControl("textfield").addListener("changeValue", function() { LT.options.lowestLevelMax[this.i] = parseInt(this.c.getValue()); }, {c:sp, i:i});
					LT.a.setElementModalInput(sp);
					cont.add(sp, {row: Math.floor(i/2), column: ((i%2 == 0) ? 1 : 3)});
				}
				this.tabPages[0].vbox.add(cont);
				this.tabPages[0].vbox.add(new qx.ui.core.Spacer(0, 10));
}		
				// ----- Page 2
{
				lab = new qx.ui.basic.Label(L("opts_set_hotkeys"));
				this.tabPages[1].vbox.add(lab);
				
				gr = new qx.ui.layout.Grid(5, 5);
				gr.setColumnMinWidth(0, 50);
				gr.setColumnMinWidth(1, 150);
				gr.setColumnMinWidth(2, 50);
				gr.setColumnMinWidth(3, 50);
				gr.setColumnMinWidth(4, 200);
				cont = new qx.ui.container.Composite(gr);
				
				btn_arr = [];

				// ----- Build hotkeys
				lab = new qx.ui.basic.Label(L("opts_hotkey_labels").lab1).set({font: "bold"});
				cont.add(lab, {column: 0, row: 0, colSpan: 3});

				cnt = 1;
				for (var i in window.louTweak.main.lou_building_id) {
					name = mb[window.louTweak.main.lou_building_id[i]].dn;
					hk = LT.options.hotkeys.build[i];
					
					lab  = new qx.ui.basic.Label(name);
					cont.add(lab, {column: 1, row: cnt});
					
					btn = new qx.ui.form.Button(hk).set({appearance: "button-recruiting", font: "bold"});
					btn.addListener("click", function() { LT.a.allowHotKey = false; this.o.btn.setLabel("..."); LT.a.mainContainer.addListenerOnce("keypress", function(e) { this.o.t.setKey(e, this.o); }, {o:this.o}); }, {o:{btn:btn, t:this, prop:i, group:"build"}});
					btn_arr.push({"btn":btn, "group":"build", "prop":i, "hk":hk});
					cont.add(btn, {column: 0, row: cnt});
					cnt++;
				}
				
				// ----- Other hotkeys
				oh = [
					[L("opts_hotkey_labels").lab2, -1, "upgrades"],
					[L("opts_hotkey_labels").upgrade, "upgrade", "upgrades"],
					[L("opts_hotkey_labels").downgrade, "downgrade", "upgrades"],
					[L("opts_hotkey_labels").minister, "minister", "upgrades"],
					[L("opts_hotkey_labels").lab4, -1, "global"],
					[L("opts_hotkey_labels").prev_city, "prevcity", "global"],
					[L("opts_hotkey_labels").next_city, "nextcity", "global"]
				];
				
				for (i=0; i<oh.length; i++) {
					if (oh[i][1] == -1) {
						lab = new qx.ui.basic.Label(oh[i][0]).set({font: "bold"});
						cont.add(lab, {column: 3, row: i, colSpan: 2});
					} else {
						name = oh[i][0];
						hk = LT.options.hotkeys[oh[i][2]][oh[i][1]];
						
						lab  = new qx.ui.basic.Label(name);
						cont.add(lab, {column: 4, row: i});
						
						btn = new qx.ui.form.Button(hk).set({appearance: "button-recruiting", font: "bold"});
						btn.addListener("click", function() { LT.a.allowHotKey = false; this.o.btn.setLabel("..."); LT.a.mainContainer.addListenerOnce("keypress", function(e) { this.o.t.setKey(e, this.o); }, {o:this.o}); }, {o:{btn:btn, t:this, prop:oh[i][1], group:oh[i][2]}});
						btn_arr.push({"btn":btn, "group":oh[i][2], "prop":oh[i][1], "hk":hk});
						cont.add(btn, {column: 3, row: i});
					}
				}
				LT.a.setUserData("btn_arr", btn_arr);
				this.tabPages[1].vbox.add(cont);
				// ----- -----
}				
				// ----- Page 3
{				
				// Color selector
				this.clrSel = new qx.ui.control.ColorPopup();
				this.clrSel.exclude();
				this.clrSel._createColorSelector();
				for (var G in this.clrSel) {
					if (this.clrSel[G] instanceof qx.ui.window.Window) {
						this.clrSel[G].set({ showMaximize: false, showMinimize: false, allowMaximize: false });
						break;
					}
				}
				this.clrSel.addListener("changeValue", function(e) {
					co = e.getData();
					if (co == null) return;

					co = qx.util.ColorUtil.rgbToHexString(qx.util.ColorUtil.stringToRgb(co));
					if (!/#/.test(co)) co = "#" + co;
					t = this.clrSel.getUserData("_type");
					id = this.clrSel.getUserData("_id");
					if (t == "incres")
						LT.options.incResClrs[id] = co;
					else if (t == "chat") {
						LT.options.chatColors[id] = co;
						chat = webfrontend.config.Config.getInstance().getChat();
						prop = ["global", "_a", "not_used", "privatein", "privateout", "social", "LoUWin"];
						if (id != 2)
							chat.channelColors[prop[id]] = co;
						else
							LT.a.chat.BgrLabel.setBackgroundColor(co);
					} else if (t == "minimap") {
						LT.options.miniMapColors[id] = co;
					}
					this.clrSel.getUserData("_btn").setBackgroundColor(co);
				}, this);
				
				this.tabPages[2].page.add(this.clrSel);
				
				// ----- Incres colors
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox(3)).set({marginLeft: 50});
				lab = new qx.ui.basic.Label(L("opts_clr_inc_res"));
				this.tabPages[2].vbox.add(lab);
				
				cl = [ "Full:", "High:", "Med:", "Low:" ];
				for (i=0; i<cl.length; i++) {
					lab = new qx.ui.basic.Label(cl[i]);
					cont.add(lab);

					btn = new qx.ui.form.Button().set({width: 20, backgroundColor: LT.options.incResClrs[i], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
					btn.addListener("click", this.setColor, {b:btn, id:i, t:this, type:"incres"});
					cont.add(btn);
					cont.add(new qx.ui.core.Spacer(10));
				}

				this.tabPages[2].vbox.add(cont);
				this.tabPages[2].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));

				// ----- Chat colors
				cont = new qx.ui.container.Composite(new qx.ui.layout.Grid(10,5)).set({marginLeft: 50});
				lab = new qx.ui.basic.Label(L("opts_clr_chat").lab);
				this.tabPages[2].vbox.add(lab);
				
				cl = [
					[L("opts_clr_chat").all, 0, 0],
					[L("opts_clr_chat").alliance, 0, 2],
					[L("opts_clr_chat").background, 0, 4],
					[L("opts_clr_chat").whisper + "1:", 0, 6],
					[L("opts_clr_chat").whisper + "2:", 1, 0],
					[L("opts_clr_chat").social, 1, 2],
					[L("opts_clr_chat").louwin, 1, 4]
				];
				for (i=0; i<cl.length; i++) {
					lab = new qx.ui.basic.Label(cl[i][0]);
					cont.add(lab, {row: cl[i][1], column: cl[i][2]});

					btn = new qx.ui.form.Button().set({width: 20, backgroundColor: LT.options.chatColors[i], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
					btn.addListener("click", this.setColor, {b:btn, id:i, t:this, type:"chat"});
					cont.add(btn, {row: cl[i][1], column: cl[i][2]+1});
				}
				this.tabPages[2].vbox.add(cont);
				this.tabPages[2].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				
				// ----- MiniMap colors
				lab = new qx.ui.basic.Label(L("opts_minimap").clrs_lab);
				this.tabPages[2].vbox.add(lab);
				
				gr = new qx.ui.layout.Grid(5, 5);
				gr.setColumnMinWidth(1, 55);
				gr.setColumnMinWidth(2, 55);
				gr.setColumnMinWidth(3, 55);
				gr.setColumnMinWidth(4, 55);
				gr.setColumnMinWidth(5, 55);
				gr.setColumnMinWidth(6, 55);
				gr.setColumnMinWidth(7, 55);

				cont = new qx.ui.container.Composite(gr);
				cl = [
					[L("opts_minimap").clr_self, 0, 1],
					[L("opts_minimap").clr_alliance, 0, 2],
					[L("opts_minimap").clr_allied, 0, 3],
					[L("opts_minimap").clr_enemy, 0, 4],
					[L("opts_minimap").clr_nap, 0, 5],
					[L("opts_minimap").clr_other, 0, 6],
					[L("opts_minimap").clr_lawless, 0, 7],
					[L("opts_minimap").show_noncastle+":", 1, 0],
					[L("opts_minimap").show_castle+":", 2, 0]
				];

				for (i=0; i<cl.length; i++) {
					lab = new qx.ui.basic.Label(cl[i][0]);
					cont.add(lab, {row: cl[i][1], column: cl[i][2]});
				}
				for (i=0; i<14; i++) {
					btn = new qx.ui.form.Button().set({maxWidth: 20, backgroundColor: LT.options.miniMapColors[(i%7)*2+Math.floor(i/7)], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
					btn.addListener("click", this.setColor, {b:btn, id:(i%7)*2+Math.floor(i/7), t:this, type:"minimap"});
					cont.add(btn, {row: Math.floor(i/7)+1, column: (i%7)+1});
				}
				lab = new qx.ui.basic.Label(L("opts_minimap").clr_moongate);
				cont.add(lab, {row: 4, column: 0});
				lab = new qx.ui.basic.Label(L("opts_minimap").clr_shrine);
				cont.add(lab, {row: 5, column: 0});
				btn = new qx.ui.form.Button().set({maxWidth: 20, backgroundColor: LT.options.miniMapColors[14], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
				btn.addListener("click", this.setColor, {b:btn, id:14, t:this, type:"minimap"});
				cont.add(btn, {row: 4, column: 1});
				btn = new qx.ui.form.Button().set({maxWidth: 20, backgroundColor: LT.options.miniMapColors[16], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
				btn.addListener("click", this.setColor, {b:btn, id:16, t:this, type:"minimap"});
				cont.add(btn, {row: 5, column: 1});
				this.tabPages[2].vbox.add(cont);
				// ----- -----
}
								

{

				// ----- Save Button
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				btn = new qx.ui.form.Button(L("opts").save).set({width: 90, marginLeft: 30});
				btn.addListener("click", this.saveOptions, this);
				cont.add(btn);

				this.expImpWin = this.createExpImpWindow();
				// ----- Export button
				btn = new qx.ui.form.Button(L("opts")['export']).set({appearance: "button-text-small", marginLeft: 280});
				btn.addListener("click", function(){
					this.expImpWin.setCaption(L("opts")['export']);
					this.expImpWin.setUserData("id", 2);
					this.expImpWin.getUserData("lab").setValue(L("opts").export_lab);
					this.expImpWin.getUserData("ta").setValue(qx.lang.Json.stringify(LT.options));
					this.expImpWin.open();
				}, this);
				cont.add(btn);
				
				// ----- Import button
				btn = new qx.ui.form.Button(L("opts")['import']).set({appearance: "button-text-small"});
				btn.addListener("click", function(){
					this.expImpWin.setCaption(L("opts")['import']);
					this.expImpWin.setUserData("id", 1);
					this.expImpWin.getUserData("lab").setValue(L("opts").import_lab);
					this.expImpWin.getUserData("ta").setValue("");
					this.expImpWin.open();
				}, this);
				cont.add(btn);
				// ----- -----
				
				// ----- Add pages to tabview
				for (i=0; i<this.tabPages.length; i++) {
					this.tabView.add(this.tabPages[i].page);
				}
				
				this.clientArea.add(this.tabView, {top: 0, right: 3, bottom: 30, left: 3});
				this.clientArea.add(cont, {right: 3, bottom: 3, left: 3});
}
			},
			members: {
				tabView: null,
				tabPages: null,
				clrSel: null,
				expImpWin: null,
				setKey: function(e, o) {
					if (LT.a.getCurrentOverlay() != o.t) {
						LT.a.allowHotKey = true;
						return;
					}
					key = e.getKeyIdentifier();
					ch = null;
					cb = null;
					ba = LT.a.getUserData("btn_arr");
					for (i=0; i<ba.length; i++) {
						if (ba[i].group == o.group && ba[i].hk == key)
							ch = ba[i];
						if (ba[i].btn == o.btn)
							cb = ba[i];
					}
					
					if (!/,/.test(key)) {
						if (key != "Delete") {
							if (o.group == "global" && /[BCMEUL]/.test(key)) {// global hotkeys B,C,M,R,U,L,(S,X,[,]), E prior to asscession
								o.btn.setLabel(LT.options.hotkeys[o.group][o.prop]);
								LT.a.allowHotKey = true;
								return;
							}
							if (ch) {
								LT.options.hotkeys[o.group][ch.prop] = "";
								ch.btn.setLabel("");
								ch.hk = "";
							}
							LT.options.hotkeys[o.group][o.prop] = key;
							cb.btn.setLabel(key);
							cb.hk = key;
						} else {
							LT.options.hotkeys[o.group][o.prop] = "";
							cb.btn.setLabel("");
							cb.hk = "";
						}
					}
					LT.a.allowHotKey = true;
				},
				setColor: function() {
					cs = this.t.clrSel;
					cs.setUserData("_id", this.id);
					cs.setUserData("_btn", this.b);
					cs.setUserData("_type", this.type);
					cs.moveTo(100, 50);
					if (this.type == "incres")
						cs.setValue(LT.options.incResClrs[this.id]);
					else if (this.type == "chat")
						cs.setValue(LT.options.chatColors[this.id]);
					else if (this.type == "minimap")
						cs.setValue(LT.options.miniMapColors[this.id]);
					cs.show();
				},
				saveOptions: function() {
					str = qx.lang.Json.stringify(LT.options);
					localStorage.setItem("LT_options", str);
					LT.a.switchOverlay(null);
				},
				createExpImpWindow: function() {
					win = new qx.ui.window.Window("");
					win.setLayout(new qx.ui.layout.VBox(10));
					win.set({showMaximize: false, showMinimize: false, allowMaximize: false});
					win.setWidth(450);
					win.setHeight(200);
					//win.open();
					LT.a.getRoot().add(win, {left:250, top:200});

					lab = new qx.ui.basic.Label("");
					win.add(lab);
					win.setUserData("lab", lab);
					
					ta = new qx.ui.form.TextArea(qx.lang.Json.stringify(LT.options));
					ta.addListener("click", function(){this.selectAllText();});
					win.add(ta, {height: 65});
					win.setUserData("ta", ta);
					btn = new qx.ui.form.Button("OK").set({maxWidth: 50, alignX: "center"});
					btn.addListener("click", function(){
						id = this.getUserData("id");
						if (id == 1) {
							txt = this.getUserData("ta").getValue();
							try {
								obj = qx.lang.Json.parse(txt);
							} catch(e) { obj = "error"; }
							if (typeof obj == "object" && obj != null) {
								LT.options = qx.lang.Json.parse(txt);
								localStorage.setItem("LT_options", txt);
								this.close();
							} else {
								alert(L("opts").import_invalid);
							}
						} else if (id == 2) {
							this.close();
						}
					}, win);
					win.add(btn);
					return win;
				},
			}
		});
		qx.Class.define("louTweak.incomingResourcesLabel", {
			extend: qx.core.Object,
			construct: function () {
				m = webfrontend.res.Main.getInstance();
				this.incResCont = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.incResContBgr = new qx.ui.basic.Image("");
				this.incResContBgr.setWidth(338);
				this.incResContBgr.setHeight(69);
				this.incResCont.add(this.incResContBgr, {left: 0, top: 0});
				this.incResLab = new qx.ui.basic.Label("Incoming resources").set({font: "bold", textColor: "#ffCC82"});
				this.incResCont.add(this.incResLab, {left: 8, top: 3});
				this.incResLabNext = new qx.ui.basic.Label("Next arrival in:").set({font: "bold", width: 150, textAlign: "right", textColor: "#ffCC82"});
				this.incResCont.add(this.incResLabNext, {left: 180, top: 3});
				this.incResLabTr = new qx.ui.basic.Label("TR:").set({font: "bold", textColor: "#ffCC82"});
				this.incResCont.add(this.incResLabTr, {left: 6, top: 38});
				this.incResLabFs = new qx.ui.basic.Label("FS:").set({font: "bold", textColor: "#ffCC82"});
				this.incResCont.add(this.incResLabFs, {left: 7, top: 50});
				for (i=0; i<4; i++) {
					imgo = m.getFileInfo(m.resources[i+1].i);
					incResImg = new qx.ui.basic.Image(webfrontend.config.Config.getInstance().getUIImagePath(imgo.url));
					incResImg.setHeight(22);
					incResImg.setWidth(20);
					incResImg.setScale(true);
					this.incResCont.add(incResImg, {top: 17, left: 5 + 83*i});
					incResLab = new qx.ui.basic.Label("").set({width: 62, textAlign: "center", font: "bold"});
					this.incResCont.setUserData("incResLab" + (i+1), incResLab);
					this.incResCont.add(incResLab, {top: 21, left: 27 + 82*i});
					incResLab = new qx.ui.basic.Label("").set({width: 62, textAlign: "center", font: "bold"});
					this.incResCont.setUserData("incResLabTot" + (i+1), incResLab);
					this.incResCont.add(incResLab, {top: 38, left: 27 + 82*i});
					incResLab = new qx.ui.basic.Label("").set({width: 62, textAlign: "center", font: "bold"});
					this.incResCont.setUserData("incResLabFree" + (i+1), incResLab);
					this.incResCont.add(incResLab, {top: 50, left: 27 + 82*i});
				}
				
				webfrontend.base.Timer.getInstance().addListener("uiTick", this.updateIncResCont, this);
			},
			members: {
				incResCont: null,
				incResContBgr: null,
				incResLab: null,
				incResLabNext: null,
				incResLabTr: null,
				incResLabFs: null,
				updateIncResCont: function() {
					var c = webfrontend.data.City.getInstance();
					it = c.getTradeIncoming();
					ot = c.getTradeOrders();
					if (LT.options.showIncResCont == 0) {
						this.incResCont.setVisibility("excluded");
						return;
					}
					if (it == null || it == undefined) {
						if (LT.options.showIncResCont == 2) {
							this.incResCont.setVisibility("excluded");
							return;
						}
						this.incResCont.setVisibility("visible");
						it = [];
					}
					this.incResCont.setVisibility("visible");
					var resVal = [0,0,0,0,0,-1]; // 0 - last trader, 1-4 res, 5 - first trader
					for (i=0; i<it.length; i++) {
						for (j=0; j<it[i].resources.length; j++) {
							resVal[it[i].resources[j].type] += it[i].resources[j].count;
						}
						if (it[i].end > resVal[0])
							resVal[0] = it[i].end;
						if (resVal[5] == -1 || it[i].end < resVal[5])
							resVal[5] = it[i].end;
					}

					for (i=1; i<5; i++) {
						freeSpc = 0;
						curVal = c.getResourceCount(i);
						curDel = (c.resources[i] == undefined ? 0 : c.resources[i].delta);
						curMax = c.getResourceMaxStorage(i);
						dateNow = new Date().getTime();
						this.incResCont.getUserData("incResLab" + i).setTextColor("#FFCC82");
						this.incResCont.getUserData("incResLab" + i).setValue(LT.thSep(resVal[i]));
						ft = 0;
						if (i == 4) {
							fc = Math.round(c.getFoodConsumption() * 3600);
							fcs = Math.round(c.getFoodConsumptionSupporter() * 3600);
							ft = c.getResourceGrowPerHour(i) - fc - fcs;
						}
						if (it.length > 0) {
							timeSpan = resVal[0] - st.getServerStep();
							resAtArrival = Math.floor(curVal + ((i == 4) ? ft*timeSpan/3600 : timeSpan * curDel) + resVal[i]);
							
							if (curVal == curMax)
								freeSpc = -resVal[i];
							else
								freeSpc = curMax - resAtArrival;
								
							if (resAtArrival > curMax) resAtArrival = curMax;
						} else {
							resAtArrival = Math.floor(curVal);
							freeSpc = curMax - curVal;
						}
						this.incResCont.getUserData("incResLabTot" + i).setValue(LT.thSep(resAtArrival));
						this.incResCont.getUserData("incResLabFree" + i).setValue(LT.thSep(Math.floor(freeSpc)));
						
						if (freeSpc < 0) {
							clr = LT.options.incResClrs[0];
						} else {
							clr = "#FFCC82";
						}
						this.incResCont.getUserData("incResLabFree" + i).setTextColor(clr);
						
						r = resAtArrival/curMax;
						clr = LT.options.incResClrs[3];
						if (r > 0) {
							if (r >= 1.0) {
								clr = LT.options.incResClrs[0];
							} else if (r >= 0.9) {
								clr = LT.options.incResClrs[1];
							} else if (r >= 0.75) {
								clr = LT.options.incResClrs[2];
							} else {
								clr = LT.options.incResClrs[3];
							}
						}
						this.incResCont.getUserData("incResLabTot" + i).setTextColor(clr);
					}
					
					if (it.length > 0) {
						timeSpan = resVal[5] - st.getServerStep();
						this.incResLabNext.setValue("Next arrival in: " + webfrontend.Util.getTimespanString(timeSpan));
					} else
						this.incResLabNext.setValue("");
				}
			}
		});
		qx.Class.define("louTweak.optionsPage", {
			extend: webfrontend.gui.OverlayWidget,
			construct: function() {
				webfrontend.gui.OverlayWidget.call(this);

				this.clientArea.setLayout(new qx.ui.layout.Canvas());
				this.setTitle("LoU Tweak Options");
				this.tabView = new qx.ui.tabview.TabView().set({contentPaddingLeft: 15, contentPaddingRight: 10, contentPaddingTop: 10, contentPaddingBottom: 10});
				this.tabPages = [
					{name:"General", page:null, vbox:null},
					{name:"Hotkeys", page:null, vbox:null},
					{name:"Colors", page:null, vbox:null}
				];
				for (i=0; i<this.tabPages.length; i++) {
					page = new qx.ui.tabview.Page(this.tabPages[i].name);
					page.setLayout(new qx.ui.layout.Canvas());
					vbox = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
					scroll = new qx.ui.container.Scroll(vbox);
					page.add(scroll, {top: 0, left: 0, right: 0, bottom: 0});
					this.tabPages[i].vbox = vbox;
					this.tabPages[i].page = page;
				}
				
				// ----- Page 1
{
				// ----- Switch to alliance tab
				cb = new qx.ui.form.CheckBox(L("opts_switch_to_ally_tab"));
				if (LT.options.switchToAllyTab)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.switchToAllyTab = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);

				// ----- Chat max lines / transparency
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_max_chatlines")).set({paddingTop: 4});
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				sp = new webfrontend.ui.SpinnerInt(10, LT.options.chatMaxLines, 100);
				sp.getChildControl("textfield").setLiveUpdate(true);
				sp.getChildControl("textfield").addListener("changeValue", function() { _val = parseInt(this.getValue()); LT.options.chatMaxLines = _val; webfrontend.config.Config.getInstance().getChat().setMaxLines(_val); }, sp);
				LT.a.setElementModalInput(sp);
				cont.add(sp);

				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_chat_opacity")).set({paddingTop: 4});
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				sp = new webfrontend.ui.SpinnerInt(0, (100-parseInt(LT.options.chatOpacity)), 100);
				sp.getChildControl("textfield").setLiveUpdate(true);
				sp.getChildControl("textfield").addListener("changeValue", function() { _val = parseInt(this.getValue()); LT.options.chatOpacity = 100 - _val; LT.a.chat.BgrLabel.setOpacity((100-_val)/100); }, sp);
				LT.a.setElementModalInput(sp);
				cont.add(sp);
				this.tabPages[0].vbox.add(cont);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- Hide 'Optimization' buttons
				cb = new qx.ui.form.CheckBox(L("opts_hide_optimize"));
				if (LT.options.hideOptimizeBtn) {
					cb.setValue(true);
					LT.main.switchOptimizeDisplay();
				}
				cb.addListener("click", function() { LT.options.hideOptimizeBtn = this.getValue() ? true : false; LT.main.switchOptimizeDisplay(); }, cb);
				this.tabPages[0].vbox.add(cb);
				
				// ----- Hide 'Get & Use' buttons
				cb = new qx.ui.form.CheckBox(L("opts_hide_get_use"));
				if (LT.options.hideGetUseBtn) {
					cb.setValue(true);
					LT.main.switchGetUseDisplay();
				}
				cb.addListener("click", function() { LT.options.hideGetUseBtn = this.getValue() ? true : false; LT.main.switchGetUseDisplay(); }, cb);
				this.tabPages[0].vbox.add(cb);
				
				// ----- Show queue info window
				cb = new qx.ui.form.CheckBox(L("opts_show_queue_win"));
				if (LT.options.showQueueTimes)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.showQueueTimes = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);
				
				// ----- Save overlay layout in city notes
				cb = new qx.ui.form.CheckBox(L("opts_save_ss_cn"));
				if (LT.options.saveSsCn)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.saveSsCn = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);

				// ----- Requested resources limit
				cb = new qx.ui.form.CheckBox(L("opts_limit_req_res"));
				if (LT.options.resLimit)
					cb.setValue(true);
				cb.addListener("click", function() { LT.options.resLimit = this.getValue() ? true : false; }, cb);
				this.tabPages[0].vbox.add(cb);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- Incoming resources label
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_inc_res").lab);
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ L("opts_inc_res").disabled, L("opts_inc_res").always, L("opts_inc_res").context ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(rbs[i]);
					rb.setUserData("id", i);
					rb.setGroup(rg);
					cont.add(rb);
					cont.add(new qx.ui.core.Spacer(10));
				}
				
				rg.setSelection([rg.getChildren()[LT.options.showIncResCont]]);
				rg.addListener("changeSelection", function() { LT.options.showIncResCont = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);
				
				// ----- Thousands separator
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_separator").lab);
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ L("opts_separator").period, L("opts_separator").comma, L("opts_separator").space, L("opts_separator").none ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(rbs[i]);
					rb.setUserData("id", i);
					rb.setGroup(rg);
					cont.add(rb);
					cont.add(new qx.ui.core.Spacer(10));				
				}
			
				rg.setSelection([rg.getChildren()[LT.options.thousandsSeparator]]);
				rg.addListener("changeSelection", function() { LT.options.thousandsSeparator = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);

				// ----- City tag
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				cont.add(new qx.ui.core.Spacer(20));
				lab = new qx.ui.basic.Label(L("opts_city_tag").lab);
				cont.add(lab);
				cont.add(new qx.ui.core.Spacer(10));
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ L("opts_city_tag").info, L("opts_city_tag").region ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(rbs[i]);
					rb.setUserData("id", i);
					rb.setGroup(rg);
					cont.add(rb);
					cont.add(new qx.ui.core.Spacer(10));				
				}

				rg.setSelection([rg.getChildren()[LT.options.cityTag]]);
				rg.addListener("changeSelection", function() { LT.options.cityTag = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);

				// ----- LoU Tweak language
				gr = new qx.ui.layout.Grid(0, 5);
				gr.setColumnMinWidth(0, 120);
				gr.setColumnMinWidth(1, 120);
				gr.setColumnMinWidth(2, 120);
				gr.setColumnMinWidth(3, 120);
				cont = new qx.ui.container.Composite(gr).set({marginLeft: 20});
				lab = new qx.ui.basic.Label(L("opts_lang").lab + " " + L("req_restart") + ":").set({marginLeft: 20});
				this.tabPages[0].vbox.add(lab);
				
				rg = new qx.ui.form.RadioGroup();
				
				rbs = [ "en", "de", "es", "pl", "pt", "ru", "it", "fr" ];
				for (i=0; i<rbs.length; i++) {
					rb = new qx.ui.form.RadioButton(L("opts_lang")[rbs[i]]);
					rb.setUserData("id", rbs[i]);
					rb.setGroup(rg);
					cont.add(rb, {row: Math.floor(i/4), column: i%4});
				}

				rg.setSelection([rg.getChildren()[LT.main.langToId(LT.options.userLang)]]);
				rg.addListener("changeSelection", function() { LT.options.userLang = this.getSelection()[0].getUserData("id"); }, rg);
				this.tabPages[0].vbox.add(cont);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- MiniMap
				gr = new qx.ui.layout.Grid(0, 9);
				gr.setColumnMinWidth(0, 80);
				gr.setColumnMinWidth(1, 60);
				gr.setColumnMinWidth(2, 60);
				gr.setColumnMinWidth(3, 60);
				gr.setColumnMinWidth(4, 60);
				gr.setColumnAlign(0, "right", "middle");
				gr.setColumnAlign(1, "center", "middle");
				gr.setColumnAlign(2, "center", "middle");
				gr.setColumnAlign(3, "center", "middle");
				gr.setColumnAlign(4, "center", "middle");
				cgb = new qx.ui.container.Composite(gr).set({marginLeft: 20});
				this.setUserData("mmcb", cgb);
				//cgb.setVisibility("excluded");
				
				cb = new qx.ui.form.CheckBox(L("opts_minimap").enable_lab);
					if (LT.options.showMiniMap) {
						cb.setValue(true);
						this.getUserData("mmcb").setVisibility("visible");
					}
				cb.addListener("click", function() {
					LT.options.showMiniMap = this.getValue() ? true : false;
					LT.main.optionsPage.getUserData("mmcb").setVisibility((this.getValue() ? "visible" : "excluded"));
					LT.main.miniMap.clientArea.setVisibility((this.getValue() ? "visible" : "excluded"));
				}, cb);
						
				this.tabPages[0].vbox.add(cb);
				
				cbs = [
					[L("opts_minimap").show_cities, 0, 0],
					[L("opts_minimap").show_none, 0, 1],
					[L("opts_minimap").show_noncastle, 0, 2],
					[L("opts_minimap").show_castle, 0, 3],
					[L("opts_minimap").show_all, 0, 4],
					[L("opts_minimap").show_self, 1, 0],
					[L("opts_minimap").show_alliance, 2, 0],
					[L("opts_minimap").show_allied, 3, 0],
					[L("opts_minimap").show_enemy, 4, 0],
					[L("opts_minimap").show_nap, 5, 0],
					[L("opts_minimap").show_other, 6, 0],
					[L("opts_minimap").show_lawless, 7, 0]
				];
				for (i=0; i<cbs.length; i++) {
					lab = new qx.ui.basic.Label(cbs[i][0]);
					cgb.add(lab, {row:cbs[i][1], column:cbs[i][2]});
				}
				lab = new qx.ui.basic.Label(L("opts_minimap").show_moongate);
				cgb.add(lab, {row:9, column:0});
				lab = new qx.ui.basic.Label(L("opts_minimap").show_shrine);
				cgb.add(lab, {row:10, column:0});
				
				for (j=0; j<7; j++) {
					rg = new qx.ui.form.RadioGroup();
					for (i=0; i<4; i++) {
						rb = new qx.ui.form.RadioButton(null);
						rb.setUserData("id", i);
						rb.setGroup(rg);
						cgb.add(rb, {row:j+1, column:i+1});
					}
					rg.setSelection([rg.getChildren()[LT.options.miniMapMark[j]]]);
					rg.addListener("changeSelection", function() { LT.options.miniMapMark[this.it] = this.g.getSelection()[0].getUserData("id"); }, {g:rg, it:j});
				}
				rg = new qx.ui.form.RadioGroup();
				rb = new qx.ui.form.RadioButton(L("no")); rb.setUserData("id", 0); rb.setGroup(rg); cgb.add(rb, {row:9, column:1});
				rb = new qx.ui.form.RadioButton(L("yes")); rb.setUserData("id", 1); rb.setGroup(rg); cgb.add(rb, {row:9, column:2});
				rg.setSelection([rg.getChildren()[LT.options.miniMapMark[7]]]);
				rg.addListener("changeSelection", function() { LT.options.miniMapMark[7] = this.getSelection()[0].getUserData("id"); }, rg);
				rg = new qx.ui.form.RadioGroup();
				rb = new qx.ui.form.RadioButton(L("no")); rb.setUserData("id", 0); rb.setGroup(rg); cgb.add(rb, {row:10, column:1});
				rb = new qx.ui.form.RadioButton(L("yes")); rb.setUserData("id", 1); rb.setGroup(rg); cgb.add(rb, {row:10, column:2});
				rg.setSelection([rg.getChildren()[LT.options.miniMapMark[8]]]);
				rg.addListener("changeSelection", function() { LT.options.miniMapMark[8] = this.getSelection()[0].getUserData("id"); }, rg);

				if (!LT.options.showMiniMap) {
					this.getUserData("mmcb").setVisibility("excluded");
				}
				this.tabPages[0].vbox.add(cgb);
				this.tabPages[0].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				// ----- -----
				
				// ----- Lowest level upgrades
				gr = new qx.ui.layout.Grid(0, 9);
				gr.setColumnMinWidth(0, 130);
				gr.setColumnMinWidth(1, 130);
				gr.setColumnMinWidth(2, 130);
				gr.setColumnMinWidth(3, 130);
				cont = new qx.ui.container.Composite(gr);
				
				lab = new qx.ui.basic.Label(L("opts_lowest_lvl").lab1);
				this.tabPages[0].vbox.add(lab);
				
				_bids = [47,48,50,4,5,49,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,36,37,38,39,40,41,42,43,44,45,46,12,23];
				mb = webfrontend.res.Main.getInstance().buildings;
				for (i=0; i<34; i++) {
					cb = new qx.ui.form.CheckBox(mb[_bids[i]].dn);
					if (LT.options.lowestLevelUpgradeIDs[i] != "")
						cb.setValue(true);
					cb.addListener("click", function() { LT.options.lowestLevelUpgradeIDs[this.i] = this.c.getValue() ? this.b : ""; }, {c:cb, b:_bids[i], i:i});
					cont.add(cb, {column: i%4, row: Math.floor(i/4)});
				}			
				this.tabPages[0].vbox.add(cont);				
				
				// ----- Level limits
				lab = new qx.ui.basic.Label(L("opts_lowest_lvl").lab2);
				this.tabPages[0].vbox.add(lab);
				
				gr = new qx.ui.layout.Grid(4, 4);
				gr.setColumnMinWidth(0, 60);
				gr.setColumnMinWidth(2, 60);
				gr.setColumnAlign(0, "right", "middle");
				gr.setColumnAlign(2, "right", "middle");
				cont = new qx.ui.container.Composite(gr);
				bTypesLabels = [ L("opts_lowest_lvl").towers, L("opts_lowest_lvl").military, L("opts_lowest_lvl").resource, L("opts_lowest_lvl").cottage, L("opts_lowest_lvl").barracks, L("opts_lowest_lvl").utilities ];
				for (i=0; i<6; i++) {
					lab = new qx.ui.basic.Label(bTypesLabels[i]);
					cont.add(lab, {row: Math.floor(i/2), column: ((i%2 == 0) ? 0 : 2)});
					sp = new webfrontend.ui.SpinnerInt(0, LT.options.lowestLevelMax[i], 10);
					sp.getChildControl("textfield").setLiveUpdate(true);
					sp.getChildControl("textfield").addListener("changeValue", function() { LT.options.lowestLevelMax[this.i] = parseInt(this.c.getValue()); }, {c:sp, i:i});
					LT.a.setElementModalInput(sp);
					cont.add(sp, {row: Math.floor(i/2), column: ((i%2 == 0) ? 1 : 3)});
				}
				this.tabPages[0].vbox.add(cont);
				this.tabPages[0].vbox.add(new qx.ui.core.Spacer(0, 10));
}		
				// ----- Page 2
{
				lab = new qx.ui.basic.Label(L("opts_set_hotkeys"));
				this.tabPages[1].vbox.add(lab);
				
				gr = new qx.ui.layout.Grid(5, 5);
				gr.setColumnMinWidth(0, 50);
				gr.setColumnMinWidth(1, 150);
				gr.setColumnMinWidth(2, 50);
				gr.setColumnMinWidth(3, 50);
				gr.setColumnMinWidth(4, 200);
				cont = new qx.ui.container.Composite(gr);
				
				btn_arr = [];

				// ----- Build hotkeys
				lab = new qx.ui.basic.Label(L("opts_hotkey_labels").lab1).set({font: "bold"});
				cont.add(lab, {column: 0, row: 0, colSpan: 3});

				cnt = 1;
				for (var i in window.louTweak.main.lou_building_id) {
					name = mb[window.louTweak.main.lou_building_id[i]].dn;
					hk = LT.options.hotkeys.build[i];
					
					lab  = new qx.ui.basic.Label(name);
					cont.add(lab, {column: 1, row: cnt});
					
					btn = new qx.ui.form.Button(hk).set({appearance: "button-recruiting", font: "bold"});
					btn.addListener("click", function() { LT.a.allowHotKey = false; this.o.btn.setLabel("..."); LT.a.mainContainer.addListenerOnce("keypress", function(e) { this.o.t.setKey(e, this.o); }, {o:this.o}); }, {o:{btn:btn, t:this, prop:i, group:"build"}});
					btn_arr.push({"btn":btn, "group":"build", "prop":i, "hk":hk});
					cont.add(btn, {column: 0, row: cnt});
					cnt++;
				}
				
				// ----- Other hotkeys
				oh = [
					[L("opts_hotkey_labels").lab2, -1, "upgrades"],
					[L("opts_hotkey_labels").upgrade, "upgrade", "upgrades"],
					[L("opts_hotkey_labels").downgrade, "downgrade", "upgrades"],
					[L("opts_hotkey_labels").minister, "minister", "upgrades"],
					[L("opts_hotkey_labels").lab4, -1, "global"],
					[L("opts_hotkey_labels").prev_city, "prevcity", "global"],
					[L("opts_hotkey_labels").next_city, "nextcity", "global"]
				];
				
				for (i=0; i<oh.length; i++) {
					if (oh[i][1] == -1) {
						lab = new qx.ui.basic.Label(oh[i][0]).set({font: "bold"});
						cont.add(lab, {column: 3, row: i, colSpan: 2});
					} else {
						name = oh[i][0];
						hk = LT.options.hotkeys[oh[i][2]][oh[i][1]];
						
						lab  = new qx.ui.basic.Label(name);
						cont.add(lab, {column: 4, row: i});
						
						btn = new qx.ui.form.Button(hk).set({appearance: "button-recruiting", font: "bold"});
						btn.addListener("click", function() { LT.a.allowHotKey = false; this.o.btn.setLabel("..."); LT.a.mainContainer.addListenerOnce("keypress", function(e) { this.o.t.setKey(e, this.o); }, {o:this.o}); }, {o:{btn:btn, t:this, prop:oh[i][1], group:oh[i][2]}});
						btn_arr.push({"btn":btn, "group":oh[i][2], "prop":oh[i][1], "hk":hk});
						cont.add(btn, {column: 3, row: i});
					}
				}
				LT.a.setUserData("btn_arr", btn_arr);
				this.tabPages[1].vbox.add(cont);
				// ----- -----
}				
				// ----- Page 3
{				
				// Color selector
				this.clrSel = new qx.ui.control.ColorPopup();
				this.clrSel.exclude();
				this.clrSel._createColorSelector();
				for (var G in this.clrSel) {
					if (this.clrSel[G] instanceof qx.ui.window.Window) {
						this.clrSel[G].set({ showMaximize: false, showMinimize: false, allowMaximize: false });
						break;
					}
				}
				this.clrSel.addListener("changeValue", function(e) {
					co = e.getData();
					if (co == null) return;

					co = qx.util.ColorUtil.rgbToHexString(qx.util.ColorUtil.stringToRgb(co));
					if (!/#/.test(co)) co = "#" + co;
					t = this.clrSel.getUserData("_type");
					id = this.clrSel.getUserData("_id");
					if (t == "incres")
						LT.options.incResClrs[id] = co;
					else if (t == "chat") {
						LT.options.chatColors[id] = co;
						chat = webfrontend.config.Config.getInstance().getChat();
						prop = ["global", "_a", "not_used", "privatein", "privateout", "social", "LoUWin"];
						if (id != 2)
							chat.channelColors[prop[id]] = co;
						else
							LT.a.chat.BgrLabel.setBackgroundColor(co);
					} else if (t == "minimap") {
						LT.options.miniMapColors[id] = co;
					}
					this.clrSel.getUserData("_btn").setBackgroundColor(co);
				}, this);
				
				this.tabPages[2].page.add(this.clrSel);
				
				// ----- Incres colors
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox(3)).set({marginLeft: 50});
				lab = new qx.ui.basic.Label(L("opts_clr_inc_res"));
				this.tabPages[2].vbox.add(lab);
				
				cl = [ "Full:", "High:", "Med:", "Low:" ];
				for (i=0; i<cl.length; i++) {
					lab = new qx.ui.basic.Label(cl[i]);
					cont.add(lab);

					btn = new qx.ui.form.Button().set({width: 20, backgroundColor: LT.options.incResClrs[i], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
					btn.addListener("click", this.setColor, {b:btn, id:i, t:this, type:"incres"});
					cont.add(btn);
					cont.add(new qx.ui.core.Spacer(10));
				}

				this.tabPages[2].vbox.add(cont);
				this.tabPages[2].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));

				// ----- Chat colors
				cont = new qx.ui.container.Composite(new qx.ui.layout.Grid(10,5)).set({marginLeft: 50});
				lab = new qx.ui.basic.Label(L("opts_clr_chat").lab);
				this.tabPages[2].vbox.add(lab);
				
				cl = [
					[L("opts_clr_chat").all, 0, 0],
					[L("opts_clr_chat").alliance, 0, 2],
					[L("opts_clr_chat").background, 0, 4],
					[L("opts_clr_chat").whisper + "1:", 0, 6],
					[L("opts_clr_chat").whisper + "2:", 1, 0],
					[L("opts_clr_chat").social, 1, 2],
					[L("opts_clr_chat").louwin, 1, 4]
				];
				for (i=0; i<cl.length; i++) {
					lab = new qx.ui.basic.Label(cl[i][0]);
					cont.add(lab, {row: cl[i][1], column: cl[i][2]});

					btn = new qx.ui.form.Button().set({width: 20, backgroundColor: LT.options.chatColors[i], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
					btn.addListener("click", this.setColor, {b:btn, id:i, t:this, type:"chat"});
					cont.add(btn, {row: cl[i][1], column: cl[i][2]+1});
				}
				this.tabPages[2].vbox.add(cont);
				this.tabPages[2].vbox.add(new qx.ui.core.Widget().set({ backgroundColor: "#bd966d", height: 1, allowGrowX: true}));
				
				// ----- MiniMap colors
				lab = new qx.ui.basic.Label(L("opts_minimap").clrs_lab);
				this.tabPages[2].vbox.add(lab);
				
				gr = new qx.ui.layout.Grid(5, 5);
				gr.setColumnMinWidth(1, 55);
				gr.setColumnMinWidth(2, 55);
				gr.setColumnMinWidth(3, 55);
				gr.setColumnMinWidth(4, 55);
				gr.setColumnMinWidth(5, 55);
				gr.setColumnMinWidth(6, 55);
				gr.setColumnMinWidth(7, 55);

				cont = new qx.ui.container.Composite(gr);
				cl = [
					[L("opts_minimap").clr_self, 0, 1],
					[L("opts_minimap").clr_alliance, 0, 2],
					[L("opts_minimap").clr_allied, 0, 3],
					[L("opts_minimap").clr_enemy, 0, 4],
					[L("opts_minimap").clr_nap, 0, 5],
					[L("opts_minimap").clr_other, 0, 6],
					[L("opts_minimap").clr_lawless, 0, 7],
					[L("opts_minimap").show_noncastle+":", 1, 0],
					[L("opts_minimap").show_castle+":", 2, 0]
				];

				for (i=0; i<cl.length; i++) {
					lab = new qx.ui.basic.Label(cl[i][0]);
					cont.add(lab, {row: cl[i][1], column: cl[i][2]});
				}
				for (i=0; i<14; i++) {
					btn = new qx.ui.form.Button().set({maxWidth: 20, backgroundColor: LT.options.miniMapColors[(i%7)*2+Math.floor(i/7)], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
					btn.addListener("click", this.setColor, {b:btn, id:(i%7)*2+Math.floor(i/7), t:this, type:"minimap"});
					cont.add(btn, {row: Math.floor(i/7)+1, column: (i%7)+1});
				}
				lab = new qx.ui.basic.Label(L("opts_minimap").clr_moongate);
				cont.add(lab, {row: 4, column: 0});
				lab = new qx.ui.basic.Label(L("opts_minimap").clr_shrine);
				cont.add(lab, {row: 5, column: 0});
				btn = new qx.ui.form.Button().set({maxWidth: 20, backgroundColor: LT.options.miniMapColors[14], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
				btn.addListener("click", this.setColor, {b:btn, id:14, t:this, type:"minimap"});
				cont.add(btn, {row: 4, column: 1});
				btn = new qx.ui.form.Button().set({maxWidth: 20, backgroundColor: LT.options.miniMapColors[16], padding: [5,15,5,15], decorator: new qx.ui.decoration.Single(1, "solid", "#b2956e"), cursor: "pointer"});
				btn.addListener("click", this.setColor, {b:btn, id:16, t:this, type:"minimap"});
				cont.add(btn, {row: 5, column: 1});
				this.tabPages[2].vbox.add(cont);
				// ----- -----
}
								

{

				// ----- Save Button
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
				btn = new qx.ui.form.Button(L("opts").save).set({width: 90, marginLeft: 30});
				btn.addListener("click", this.saveOptions, this);
				cont.add(btn);

				this.expImpWin = this.createExpImpWindow();
				// ----- Export button
				btn = new qx.ui.form.Button(L("opts")['export']).set({appearance: "button-text-small", marginLeft: 280});
				btn.addListener("click", function(){
					this.expImpWin.setCaption(L("opts")['export']);
					this.expImpWin.setUserData("id", 2);
					this.expImpWin.getUserData("lab").setValue(L("opts").export_lab);
					this.expImpWin.getUserData("ta").setValue(qx.lang.Json.stringify(LT.options));
					this.expImpWin.open();
				}, this);
				cont.add(btn);
				
				// ----- Import button
				btn = new qx.ui.form.Button(L("opts")['import']).set({appearance: "button-text-small"});
				btn.addListener("click", function(){
					this.expImpWin.setCaption(L("opts")['import']);
					this.expImpWin.setUserData("id", 1);
					this.expImpWin.getUserData("lab").setValue(L("opts").import_lab);
					this.expImpWin.getUserData("ta").setValue("");
					this.expImpWin.open();
				}, this);
				cont.add(btn);
				// ----- -----
				
				// ----- Add pages to tabview
				for (i=0; i<this.tabPages.length; i++) {
					this.tabView.add(this.tabPages[i].page);
				}
				
				this.clientArea.add(this.tabView, {top: 0, right: 3, bottom: 30, left: 3});
				this.clientArea.add(cont, {right: 3, bottom: 3, left: 3});
}
			},
			members: {
				tabView: null,
				tabPages: null,
				clrSel: null,
				expImpWin: null,
				setKey: function(e, o) {
					if (LT.a.getCurrentOverlay() != o.t) {
						LT.a.allowHotKey = true;
						return;
					}
					key = e.getKeyIdentifier();
					ch = null;
					cb = null;
					ba = LT.a.getUserData("btn_arr");
					for (i=0; i<ba.length; i++) {
						if (ba[i].group == o.group && ba[i].hk == key)
							ch = ba[i];
						if (ba[i].btn == o.btn)
							cb = ba[i];
					}
					
					if (!/,/.test(key)) {
						if (key != "Delete") {
							if (o.group == "global" && /[BCMEUL]/.test(key)) {// global hotkeys B,C,M,R,U,L,(S,X,[,]), E prior to asscession
								o.btn.setLabel(LT.options.hotkeys[o.group][o.prop]);
								LT.a.allowHotKey = true;
								return;
							}
							if (ch) {
								LT.options.hotkeys[o.group][ch.prop] = "";
								ch.btn.setLabel("");
								ch.hk = "";
							}
							LT.options.hotkeys[o.group][o.prop] = key;
							cb.btn.setLabel(key);
							cb.hk = key;
						} else {
							LT.options.hotkeys[o.group][o.prop] = "";
							cb.btn.setLabel("");
							cb.hk = "";
						}
					}
					LT.a.allowHotKey = true;
				},
				setColor: function() {
					cs = this.t.clrSel;
					cs.setUserData("_id", this.id);
					cs.setUserData("_btn", this.b);
					cs.setUserData("_type", this.type);
					cs.moveTo(100, 50);
					if (this.type == "incres")
						cs.setValue(LT.options.incResClrs[this.id]);
					else if (this.type == "chat")
						cs.setValue(LT.options.chatColors[this.id]);
					else if (this.type == "minimap")
						cs.setValue(LT.options.miniMapColors[this.id]);
					cs.show();
				},
				saveOptions: function() {
					str = qx.lang.Json.stringify(LT.options);
					localStorage.setItem("LT_options", str);
					LT.a.switchOverlay(null);
				},
				createExpImpWindow: function() {
					win = new qx.ui.window.Window("");
					win.setLayout(new qx.ui.layout.VBox(10));
					win.set({showMaximize: false, showMinimize: false, allowMaximize: false});
					win.setWidth(450);
					win.setHeight(200);
					//win.open();
					LT.a.getRoot().add(win, {left:250, top:200});

					lab = new qx.ui.basic.Label("");
					win.add(lab);
					win.setUserData("lab", lab);
					
					ta = new qx.ui.form.TextArea(qx.lang.Json.stringify(LT.options));
					ta.addListener("click", function(){this.selectAllText();});
					win.add(ta, {height: 65});
					win.setUserData("ta", ta);
					btn = new qx.ui.form.Button("OK").set({maxWidth: 50, alignX: "center"});
					btn.addListener("click", function(){
						id = this.getUserData("id");
						if (id == 1) {
							txt = this.getUserData("ta").getValue();
							try {
								obj = qx.lang.Json.parse(txt);
							} catch(e) { obj = "error"; }
							if (typeof obj == "object" && obj != null) {
								LT.options = qx.lang.Json.parse(txt);
								localStorage.setItem("LT_options", txt);
								this.close();
							} else {
								alert(L("opts").import_invalid);
							}
						} else if (id == 2) {
							this.close();
						}
					}, win);
					win.add(btn);
					return win;
				},
			}
		});
		qx.Class.define("louTweak.overlayObject", {
			extend: webfrontend.vis.Entity,
			statics: {
				img: {
/* remove marker */	"0": "",
/* woodcutter */	"47": "",
/* quarry */		"48": "",
/* farm */			"50": "",
/* cottage */		"4": "",
/* marketplace */	"5": "",
/* iron mine */		"49": "",
/* sawmill */		"7": "",
/* mill */			"8": "",
/* hideout */		"9": "",
/* stonemason */	"10": "",
/* foundry */		"11": "",
/* town house */	"13": "",
/* barracks */		"14": "",
/* city guard house */"15": "",
/* training ground */"16": "",
/* stable */		"17": "",
/* workshop */		"18": "",
/* shipyard */		"19": "",
/* warehouse */		"20": "",
/* castle */		"21": "",
/* harbor */		"22": "",
/* moonglow tower */"36": "",
/* trinsic temple */"37": "",
/* background */	"bg": "",
/* exclam mark */	"-1": ""
				}
			},
			construct: function (vis, x, y, img_id) {
				webfrontend.vis.Entity.call(this);
				this.drawNode = new webfrontend.draw.ImageNode.create(vis.scene, x+4, y+4, 50, 50, this.self(arguments).img[img_id]);
				this.drawNode.setSortOrder(100000);
				this.backgroundNode = new webfrontend.draw.BackgroundTextNode(vis.scene, x, y, 58, 58, this.self(arguments).img["bg"], "");
				this.backgroundNode.setSortOrder(99999);
			},
			destruct: function() {
				if (this.drawNode) {
					this.drawNode.release();
					this.drawNode = null;
				}
				this._disposeObjects("backgroundNode");
			},
			members: {
				drawNode: null,
				backgroundNode: null
			}
		});
		qx.Class.define("louTweak.layoutWindow", {
			extend: qx.core.Object,
			statics: {
				node: {
					"28":0,	"900":0, "29":1, "901":1, "27":2, "902":2, "30":3, "903":3, "23":4, "1":5, "2":6, "3":7, "4":8,
					"5":9,	"6":10,	"7":11,	"8":12,	"9":13,	"10":14,"11":15,"12":16,"13":17,"14":18,"15":19,"16":20,"17":21,
					"18":22,"19":23,"20":24,"21":25,"22":26,"36":27,"37":28,"38":29,"39":30,"40":31,"41":32,"42":33,"43":34,
					"44":35,"45":36,"46":37,"98":38,"99":39,"-2":40,"-1":41,"97":46,"47":42,"48":43,"49":45,"50":44,"52":38,
					"53":38,"54":38,"55":38,"56":38,"57":38,"58":38,"59":38,
					"904":0, "61":0, "905":1, "62":1, "906":2, "60":2, "907":3, "63":3, //magic res
					"64":0, "65":0, "66":0, "67":0, "68":0, "69":0 // special buildings
				},
				louCityP: [
					":",".",",",";","#","W","Q","F","C","P","I","L","M","H","A","D","T","U","B","K","G", //20
					"E","Y","V","S","X","R","J","Z","#","#","#","#","#","#","#","#","#","-","#","#","#", //41
					"2","3","1","4","_" //42-45, 46
				],
				louFCityP: [
					"B","A","C","D", "","F","G","I","O","J","H","K","N","1","L","M","0","E","P","S","Q",
					"U","V","Y","Z","X","T","R","W", "", "", "", "", "", "", "", "", "","0", "","0", "",
					"2","3","5","4","0"
				],
				fcpToSs: {
					"B":":", "A":".", "C":",", "D":";", "E":"U", "F":"W", "G":"Q", "H":"I",
					"I":"F", "J":"P", "K":"L", "L":"A", "M":"D", "N":"M", "O":"C", "P":"B",
					"Q":"G", "R":"J", "S":"K", "T":"R", "U":"E", "V":"Y", "W":"Z", "X":"X",
					"Y":"V", "Z":"S", "1":"H", "0":"-", "2":"2", "3":"3", "4":"4", "5":"1"
				},
				ssToId: {
					"2":47, "3":48, "1":50, "C": 4, "P": 5, "4":49, "L": 7, "M": 8,
					"H": 9, "A":10, "D":11, "T":12, "U":13, "B":14, "K":15, "G":16,
					"E":17, "Y":18, "V":19, "S":20, "X":21, "R":22, "J":36, "Z":37
				},
				land: "########################-------#-------#####--------#--------###---------#---------##---------#---------##------#######------##-----##-----##-----##----##-------##----##----#---------#----##----#---------#----#######---------#######----#---------#----##----#---------#----##----##-------##----##-----##-----##-----##------#######------##---------#---------##---------#---------###--------#--------#####-------#-------########################",
				water: "########################-------#-------#####--------#--------###---------#---------##---------#---------##------#######------##-----##-----##-----##----##-------##----##----#---------#----##----#---------#----#######---------#######----#---------#----##----#---------#----##----##-------##----##-----##-----##-----##------#######--__--##---------#----_##_-##---------#----_###_###--------#-----_#######-------#------_########################",
				error: {
					"resource": "invalid resource node position",
					"castle": "invalid building position (Castle)",
					"water": "invalid building position (Harbor/Shipyard)",
					"type": "invalid Sharestring type (stype => ctype)",
					"hash": "invalid Sharestring"
				}
			},
			construct: function() {
				this.win = new qx.ui.window.Window(L("layout").city);
				this.win.setLayout(new qx.ui.layout.Canvas());
				this.win.set({showMaximize: false, showMinimize: false, allowMaximize: false});
				this.win.setWidth(500);
				this.win.setHeight(350);

				this.tabView = new qx.ui.tabview.TabView().set({contentPadding: 5});
				page1 = new qx.ui.tabview.Page("Sharestring");
				page1.setLayout(new qx.ui.layout.VBox(5));
				page2 = new qx.ui.tabview.Page(L("layout").overlay);
				page2.setLayout(new qx.ui.layout.VBox(5));
				
				// Page 1
				gr = new qx.ui.layout.Grid(5, 5);
				gr.setColumnAlign(0, "right", "middle");
				gr.setColumnWidth(1, 380);
				cont = new qx.ui.container.Composite(gr);
				this.ssTa1 = new qx.ui.form.TextArea("").set({height: 60});
				this.ssTa1.addListener("click", function(){this.selectAllText();});
				cont.add(new qx.ui.basic.Label("Sharestring:"), {row: 0, column: 0});
				cont.add(this.ssTa1, {row: 0, column: 1});
				this.ssTa2 = new qx.ui.form.TextArea("").set({height: 60});
				this.ssTa2.addListener("click", function(){this.selectAllText();});
				cont.add(new qx.ui.basic.Label("Flash Planner 1:"), {row: 1, column: 0});
				cont.add(this.ssTa2, {row: 1, column: 1});
				this.ssTa3 = new qx.ui.form.TextArea("").set({height: 60});
				this.ssTa3.addListener("click", function(){this.selectAllText();});
				cont.add(new qx.ui.basic.Label("Flash Planner 2:"), {row: 2, column: 0});
				cont.add(this.ssTa3, {row: 2, column: 1});
				page1.add(cont);
				
				this.louFCPlink = new qx.ui.basic.Label("Open in Flash City Planner 1").set({
					textColor: "#105510",
					rich: true,
					appearance: "clickable-link",
					cursor: "pointer",
					marginLeft: 310
				});
				this.louFCPlink.addListener("click", function(){LT.a.showExternal(this.cityLayout.u);}, this);
				page1.add(this.louFCPlink);
				this.louFCPlink2 = new qx.ui.basic.Label("Open in Flash City Planner 2").set({
					textColor: "#105510",
					rich: true,
					appearance: "clickable-link",
					cursor: "pointer",
					marginLeft: 310
				});
				this.louFCPlink2.addListener("click", function(){LT.a.showExternal(this.cityLayout.u2);}, this);
				page1.add(this.louFCPlink2);

				// Page 2
				this.olTa = new qx.ui.form.TextArea("").set({height: 110});
				page2.add(this.olTa);

				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox(10));
				btn = new qx.ui.form.Button(L("layout").apply).set({maxWidth: 150, appearance: "button-text-small"});
				btn.addListener("click", this.applyLayout, this);
				cont.add(btn);

				btn = new qx.ui.form.Button(L("layout").remove).set({maxWidth: 150, appearance: "button-text-small"});
				btn.addListener("click", this.removeLayout, this);
				cont.add(btn);
				
				this.errorLabel = new qx.ui.basic.Label("").set({ textColor: "#FF0000", marginLeft: 20, font: "bold"});
				cont.add(this.errorLabel);
				page2.add(cont);
				
				// ----- Export / Import sharestrings
				cont = new qx.ui.container.Composite(new qx.ui.layout.HBox(10));

				this.expImpWin = this.createExpImpWindow();
				// ----- Export button
				btn = new qx.ui.form.Button(L("opts")['export']).set({appearance: "button-text-small"});
				btn.addListener("click", function(){
					this.expImpWin.setCaption(L("opts")['export']);
					this.expImpWin.setUserData("id", 2);
					this.expImpWin.getUserData("ta").setValue(qx.lang.Json.stringify(this.cityLayouts));
					this.expImpWin.open();
				}, this);
				cont.add(btn);
				
				// ----- Import button
				btn = new qx.ui.form.Button(L("opts")['import']).set({appearance: "button-text-small"});
				btn.addListener("click", function(){
					this.expImpWin.setCaption(L("opts")['import']);
					this.expImpWin.setUserData("id", 1);
					this.expImpWin.getUserData("ta").setValue("");
					this.expImpWin.open();
				}, this);
				cont.add(btn);
				
				page2.add(cont);

				this.tabView.add(page1);
				this.tabView.add(page2);
				this.win.add(this.tabView, {top: 0, right: 3, bottom: 30, left: 3});
				
				btn = new qx.ui.form.Button("OK").set({width: 75});
				btn.addListener("click", function(){this.tabView.setSelection([this.tabView.getChildren()[0]]); this.win.close()}, this);
				this.win.add(btn, {bottom: 0, right: 20});
				
				LT.a.getRoot().add(this.win, {left:250, top:200});
				this.srvName = webfrontend.data.Server.getInstance().getName();
				this.loadCityLayouts();
			},
			members: {
				cityLayout: null,
				cityLayouts: null,
				olTa: null,
				ssTa1: null,
				ssTa2: null,
				ssTa3: null,
				louFCPlink: null,
				errorLabel: null,
				tabView: null,
				win: null,
				oObjs: null,
				srvName: null,
				open: function() {
					this.win.open();
					this.ssTa1.setValue(this.cityLayout.s);
					this.ssTa2.setValue(this.cityLayout.u);
					this.ssTa3.setValue(this.cityLayout.u2);
					if (this.cityLayouts[this.srvName].hasOwnProperty(webfrontend.data.City.getInstance().getId() + "o"))
						this.olTa.setValue(this.cityLayouts[this.srvName][webfrontend.data.City.getInstance().getId() + "o"]);
					else this.olTa.setValue("");
					this.errorLabel.setValue("");
				},
				loadCityLayouts: function() {
					_str = localStorage.getItem("LT_cityLayouts");
					this.cityLayouts = {};
					this.cityLayouts[this.srvName] = {};
					if (_str) {
						_scl = qx.lang.Json.parse(_str);
						if (_scl.hasOwnProperty(this.srvName))
							this.cityLayouts[this.srvName] = _scl[this.srvName];
					}
				},
				saveCityLayouts: function() {
					_str = localStorage.getItem("LT_cityLayouts");
					if (_str == null) _str = '{"' + this.srvName + '":{}}';
					_scl = qx.lang.Json.parse(_str);
					_scl[this.srvName] = this.cityLayouts[this.srvName];
					_str = qx.lang.Json.stringify(_scl);
					localStorage.setItem("LT_cityLayouts", _str);
				},
				removeObjects: function() {
					if (this.oObjs != null) {
						for (i=0; i<this.oObjs.length; i++) {
							this.oObjs[i].release();
						}
						this.oObjs = null;
					}
				},
				showOverlayLayout: function(ss, or) {
				this.removeObjects();
		try {
					LT.main.getCity();
					c = LT.city;
					cgi = webfrontend.data.City.getInstance();
					if (c == null || c == undefined) {
						window.setTimeout(function(){LT.main.layoutWindow.showOverlayLayout();}, 1000);
						return;
					}
					for (i=0; i<c.length; i++) {
						if (c[i] == null) {
							window.setTimeout(function(){LT.main.layoutWindow.showOverlayLayout();}, 1000);
							return;
						}
					}
					cId = cgi.getId();
					if (LT.main.cityId != cId || qx.lang.Object.isEmpty(LT.a.visMain.selectableEntities) || LT.main.cityId != LT.a.visMain.mapid) {
						window.setTimeout(function(){LT.main.layoutWindow.showOverlayLayout();}, 2000);
						return;
					}
					
					if (this.cityLayouts[this.srvName].hasOwnProperty(cId))
						ss = this.cityLayouts[this.srvName][cId];
					if (ss == null || ss == undefined) {
						cnt = cgi.getText();
						ss = cnt.match(/\[LTS\](.+)\[\/LTS\]/);
						if (ss != null) {
							or = ss[1];
							ss = ss[1].replace(/\[[^\]]+\](\:|\;)?/g, "");
							if (ss.indexOf("map=") != -1) {
								//ss = ss.replace(/http\:\/\/www\.lou\-fcp\.co\.uk\/map\.php\?map=/, "");
								ss = ss.substring(ss.indexOf("=")+1);
								ss = this.convertToSharestring(ss);
							}
						}
					}
					// !this.validateSharestring(ss) || 
					if (ss == undefined || ss == null || LT.a.visMain.mapmode != "c") return;

					if (!this.cityLayouts[this.srvName].hasOwnProperty(cId)) {
						this.cityLayouts[this.srvName][cId] = ss;
						this.cityLayouts[this.srvName][cId + "o"] = or;
						this.saveCityLayouts();
					}

					this.oObjs = new Array();
					/*
					for (i=0; i<ss.length; i++) {
						if (!/\;|\:|\,|\.|T|#|\-|\_|W|Q|F|I/.test(ss.charAt(i))) {
							id = this.self(arguments).ssToId[ss.charAt(i)];
							if (c[i][2] != id)
								this.oObjs.push(new window.louTweak.overlayObject(LT.a.visMain, 163+128*(i%21), 67+80*Math.floor(i/21), id));
						} else if (/\-/.test(ss.charAt(i))) {
							if (c[i][2] != 98 && c[i][2] != -2 && (c[i][2] < 52 || c[i][2] > 60))
								this.oObjs.push(new window.louTweak.overlayObject(LT.a.visMain, 163+128*(i%21), 67+80*Math.floor(i/21), 0));
						} else if (/\_/.test(ss.charAt(i))) {
							if (c[i][2] != 97)
								this.oObjs.push(new window.louTweak.overlayObject(LT.a.visMain, 163+128*(i%21), 67+80*Math.floor(i/21), 0));
						}
					}*/
					for (i=0; i<ss.length; i++) {
						if (/T|#|W|Q|F|I/.test(ss.charAt(i))) continue;
						id = 0;
						if (!/\;|\:|\,|\.|\-|\_/.test(ss.charAt(i))) {
							id = this.self(arguments).ssToId[ss.charAt(i)];
							if (c[i][2] == id) continue;
						} else if (/\;|\:|\,|\./.test(ss.charAt(i))) {
							if (ss.charAt(i) == ";" && /30|903|63|907/.test(c[i][2])) continue;
							else if (ss.charAt(i) == ":" && /28|900|61|904/.test(c[i][2])) continue;
							else if (ss.charAt(i) == "," && /27|902|60|906/.test(c[i][2])) continue;
							else if (ss.charAt(i) == "." && /29|901|62|905/.test(c[i][2])) continue;
							else id = -1;
						} else if (/\-/.test(ss.charAt(i))) {
							if (c[i][2] == 98 || c[i][2] == -2 || (c[i][2] >= 52 && c[i][2] <= 60))
								continue;
						} else if (/\_/.test(ss.charAt(i))) {
							if (c[i][2] == 97)
								continue;
						}
						this.oObjs.push(new window.louTweak.overlayObject(LT.a.visMain, 163+128*(i%21), 67+80*Math.floor(i/21), id));
					}
		} catch(e) {LT.debug(e);}
				},
				generateSharestring: function() {
					try {
						LT.main.getCity();
						this.cityLayout = {"s":"", "u":"", "u2":""};
						waterCity = webfrontend.data.City.getInstance().getOnWater();
						c = LT.city;
						var sharestring = "[ShareString.1.3]" + ((waterCity) ? ";" : ":");
						var url = "http://www.lou-fcp.co.uk/map.php?map=" + ((waterCity) ? "W" : "L");
						for (i=0; i<c.length; i++) {
							sharestring += this.self(arguments).louCityP[this.self(arguments).node[c[i][2]]];
							url += this.self(arguments).louFCityP[this.self(arguments).node[c[i][2]]];
						}
						if (waterCity) url = url.substring(0,317)+url.substring(319,333);
						sharestring += "[/ShareString]";
						this.cityLayout.s = sharestring;
						this.cityLayout.u = url;
						this.cityLayout.u2 = url.replace(/http\:\/\/www\.lou\-fcp\.co\.uk\/map\.php/, "http://city.louopt.com/");
					} catch(e) { LT.debug(e); }
				},
				applyLayout: function() {
					this.errorLabel.setValue("");
					txt = this.olTa.getValue().replace(/\s/g,"");
					o = txt;
					if (txt.indexOf("ShareString") != -1) {
						t = txt.match(/\](\:|\;){1}/)[1];
						txt = txt.replace(/\[[^\]]+\](\:|\;)?/g, "");
						if (txt.length != 441) {
							this.errorLabel.setValue(this.self(arguments).error.hash);
							return;
						}
						if (webfrontend.data.City.getInstance().getOnWater() && t == ":") {
							this.errorLabel.setValue(this.self(arguments).error.type.replace(/stype/,"Land").replace(/ctype/,"Water"));
							return;
						} else if (!webfrontend.data.City.getInstance().getOnWater() && t == ";") {
							this.errorLabel.setValue(this.self(arguments).error.type.replace(/stype/,"Water").replace(/ctype/,"Land"));
							return;
						}
						//if (this.validateSharestring(txt))
						this.saveToCityNotes("a", o);
						//else return;
						this.showOverlayLayout(txt, o);
					} else if (txt.indexOf("map=") != -1) {
						txt = txt.substring(txt.indexOf("=")+1);
						if (txt.length != 294) {
							this.errorLabel.setValue(this.self(arguments).error.hash);
							return;
						}
						if (webfrontend.data.City.getInstance().getOnWater() && txt.charAt(0) == "L") {
							this.errorLabel.setValue(this.self(arguments).error.type.replace(/stype/,"Land").replace(/ctype/,"Water"));
							return;
						} else if (!webfrontend.data.City.getInstance().getOnWater() && txt.charAt(0) == "W") {
							this.errorLabel.setValue(this.self(arguments).error.type.replace(/stype/,"Water").replace(/ctype/,"Land"));
							return;
						}
						txt = this.convertToSharestring(txt);
						//if (this.validateSharestring(txt))
						this.saveToCityNotes("a", o);
						//else return;
						this.showOverlayLayout(txt, o);
					}
				},
				removeLayout: function() {
					cId = webfrontend.data.City.getInstance().getId();
					this.errorLabel.setValue("");
					this.removeObjects();
					delete this.cityLayouts[this.srvName][cId];
					delete this.cityLayouts[this.srvName][cId + "o"];
					this.saveToCityNotes("r", "");
					this.olTa.setValue("");
					this.saveCityLayouts();
				},
				convertToSharestring: function(u) {
					template = this.self(arguments).land;
					t = u.charAt(0);
					if (t == "W") {
						u = u.substring(0,242) + u.substring(244,260) + u.substring(263,278) + u.substring(280);
						template = this.self(arguments).water;
					}
					u = u.substring(1);
					c = -1;
					u = template.replace(/\-|\_/g, function(){ c++; return window.louTweak.layoutWindow.fcpToSs[u[c]]; });
					u = u.substring(0,220) + "T" + u.substring(221);
					if (t == "W") {
						wbp = [331, 332, 351, 354, 372, 376, 394, 416];
						u = u.split("");
						for (i=0; i<wbp.length; i++) {
							if (u[wbp[i]] == "-") u[wbp[i]] = "_";
						}
						u = u.join("");
					}
					return u;
				},
				validateSharestring: function(s) {
					if (s == undefined || s == null) return false;
					error = "";
					c = LT.city;
					for (i=0; i<c.length; i++) {
						if (/\;|\:|\,|\./.test(s.charAt(i))) {
							switch(s.charAt(i)) {
								case ";":
									if (c[i][2] != 30 && c[i][2] != 903 && c[i][2] != 63 && c[i][2] != 907)
										error = "resource";
									break;
								case ":":
									if (c[i][2] != 28 && c[i][2] != 900 && c[i][2] != 61 && c[i][2] != 904)
										error = "resource";
									break;
								case ",":
									if (c[i][2] != 27 && c[i][2] != 902 && c[i][2] != 60 && c[i][2] != 906)
										error = "resource";
									break;
								case ".":
									if (c[i][2] != 29 && c[i][2] != 901 && c[i][2] != 62 && c[i][2] != 905)
										error = "resource";
									break;
							}
						}
						if (c[i][2] == 21 && s.charAt(i) != "X")
							error = "castle";
						if ((/V|R|\_/.test(s.charAt(i)) && !/\b(19|22|97)\b/.test(c[i][2])) || (/\b(19|22|97)\b/.test(c[i][2]) && !/V|R|\_/.test(s.charAt(i)))) {
							error = "water";
							//LT.debug(i + " " + s.charAt(i) + " " + c[i][2]);
						}
					}
					if (s.replace(/[^X]/g,"").length > 1)
						error = "castle";
					if (error != "") {
						this.errorLabel.setValue(this.self(arguments).error[error]);
						return false;
					} else {
						return true;
					}
				},
				createExpImpWindow: function(t) {
					win = new qx.ui.window.Window("");
					win.setLayout(new qx.ui.layout.VBox(10));
					win.set({showMaximize: false, showMinimize: false, allowMaximize: false});
					win.setWidth(450);
					win.setHeight(200);
					LT.a.getRoot().add(win, {left:250, top:200});
					
					ta = new qx.ui.form.TextArea("");
					ta.addListener("click", function(){this.selectAllText();});
					win.add(ta, {height: 70});
					win.setUserData("ta", ta);
					btn = new qx.ui.form.Button("OK").set({maxWidth: 50, alignX: "center"});
					btn.addListener("click", function() {
						id = this.getUserData("id");
						if (id == 1) {
							txt = this.getUserData("ta").getValue();
							try {
								obj = qx.lang.Json.parse(txt);
							} catch(e) { obj = "error"; }
							if (typeof obj == "object" && obj != null) {
								_icl = qx.lang.Json.parse(txt); // imp ss
								if (_icl.hasOwnProperty(LT.main.layoutWindow.srvName)) {
									LT.main.layoutWindow.cityLayouts[LT.main.layoutWindow.srvName] = _icl[LT.main.layoutWindow.srvName];
									LT.main.layoutWindow.saveCityLayouts();
								}
								this.close();
							} else {
								alert(L("opts").import_invalid);
							}
						} else if (id == 2) {
							this.close();
						}
					}, win);
					win.add(btn);
					return win;
				},
				saveToCityNotes: function(c, s) {
					if (LT.options.saveSsCn == false) return;
					cgi = webfrontend.data.City.getInstance();
					cnt = cgi.getText();
					cnss = cnt.match(/\n?\[LTS\].+\[\/LTS\]/);
					if (c == "a") {
						lts = "\n[LTS]" + s + "[/LTS]";
						if (cnss != null) {
							cnt = cnt.replace(cnss[0], lts);
						} else {
							if (cnt.length + lts.length < 1000) cnt = cnt + lts;
							else return;
						}
					} else if (c == "r") {
						if (cnss != null) {
							cnt = cnt.replace(cnss[0], "");
						} else
							return;
					}
					webfrontend.net.CommandManager.getInstance().sendCommand("CityNoteSet", {
						cityid: cgi.getId(),
						reference: cgi.getReference(),
						text: cnt
					}, this, this.fireChangeVer);
					
				},
				fireChangeVer: function() {
					pgi = webfrontend.data.Player.getInstance();
					pgi.fireDataEvent("changeVersion", pgi.getVersion());
				}
			}
		});
		qx.Class.define("louTweak.miniMap", {
			extend: qx.core.Object,
			construct: function () {
				this.clientArea = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.clientArea.setWidth(200);
			
				// ----- MiniMap container
				this.miniMapCont = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.miniMapCont.setHeight(228);
				this.miniMapCont.setWidth(200);
				this.miniMapCont.setAllowGrowY(false);
				this.miniMapCont.setAllowGrowX(false);
				
				// ----- Background
				var background = new qx.ui.core.Widget();
				background.setBackgroundColor("black");
				//background.setOpacity(0.70);
				this.miniMapCont.add(background, {top: 14, left: 0, bottom: 0, right: 0});
				
				// ----- Title bar
				this.titleBar = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.titleBar.setHeight(28);
				this.titleBar.setWidth(200);
				
				var titleBarLeft = new qx.ui.basic.Image("%2BbN%2FrXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz%2FSMBAPh%2BPDwrIsAHvgABeNMLCADATZvAMByH%2Fw%2FqQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf%2BbTAICd%2BJl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA%2Fg88wAAKCRFRHgg%2FP9eM4Ors7ONo62Dl8t6r8G%2FyJiYuP%2B5c%2BrcEAAAOF0ftH%2BLC%2BzGoA7BoBt%2FqIl7gRoXgugdfeLZrIPQLUAoOnaV%2FNw%2BH48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl%2FAV%2F1s%2BX48%2FPf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H%2FLcL%2F%2Fwd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s%2BwM%2B3zUAsGo%2BAXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93%2F%2B8%2F%2FUegJQCAZkmScQAAXkQkLlTKsz%2FHCAAARKCBKrBBG%2FTBGCzABhzBBdzBC%2FxgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD%2FphCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8%2BQ8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8%2BxdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR%2BcQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI%2BksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG%2BQh8lsKnWJAcaT4U%2BIoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr%2Bh0uhHdlR5Ol9BX0svpR%2BiX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK%2BYTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI%2BpXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q%2FpH5Z%2FYkGWcNMw09DpFGgsV%2FjvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY%2FR27iz2qqaE5QzNKM1ezUvOUZj8H45hx%2BJx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4%2FOBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up%2B6Ynr5egJ5Mb6feeb3n%2Bhx9L%2F1U%2FW36p%2FVHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm%2Beb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw%2B6TvZN9un2N%2FT0HDYfZDqsdWh1%2Bc7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc%2BLpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26%2FuNu5p7ofcn8w0nymeWTNz0MPIQ%2BBR5dE%2FC5%2BVMGvfrH5PQ0%2BBZ7XnIy9jL5FXrdewt6V3qvdh7xc%2B9j5yn%2BM%2B4zw33jLeWV%2FMN8C3yLfLT8Nvnl%2BF30N%2FI%2F9k%2F3r%2F0QCngCUBZwOJgUGBWwL7%2BHp8Ib%2BOPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo%2Bqi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt%2F87fOH4p3iC%2BN7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi%2FRNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z%2Bpn5mZ2y6xlhbL%2BxW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a%2FzYnKOZarnivN7cyzytuQN5zvn%2F%2FtEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1%2B1dT1gvWd%2B1YfqGnRs%2BFYmKrhTbF5cVf9go3HjlG4dvyr%2BZ3JS0qavEuWTPZtJm6ebeLZ5bDpaql%2BaXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO%2FPLi8ZafJzs07P1SkVPRU%2BlQ27tLdtWHX%2BG7R7ht7vPY07NXbW7z3%2FT7JvttVAVVN1WbVZftJ%2B7P3P66Jqun4lvttXa1ObXHtxwPSA%2F0HIw6217nU1R3SPVRSj9Yr60cOxx%2B%2B%2Fp3vdy0NNg1VjZzG4iNwRHnk6fcJ3%2FceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w%2B0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb%2B%2B6EHTh0kX%2Fi%2Bc7vDvOXPK4dPKy2%2BUTV7hXmq86X23qdOo8%2FpPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb%2F1tWeOT3dvfN6b%2FfF9%2FXfFt1%2Bcif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v%2B3Njv3H9qwHeg89HcR%2FcGhYPP%2FpH1jw9DBY%2BZj8uGDYbrnjg%2BOTniP3L96fynQ89kzyaeF%2F6i%2FsuuFxYvfvjV69fO0ZjRoZfyl5O%2FbXyl%2FerA6xmv28bCxh6%2ByXgzMV70VvvtwXfcdx3vo98PT%2BR8IH8o%2F2j5sfVT0Kf7kxmTk%2F8EA5jz%2FGMzLdsAAAAGYktHRAD%2FAP8A%2F6C9p5MAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfaCQQTFBTXF37OAAACIklEQVQ4y3WUvW4TURCFvzN3f5wEEE0CdDQQCdFFSCiPEIQUhERLS0PavAIPkjqiSB7BCLcokUhDESMSFAkJWUqMY%2B9Q3LubdWy72ea7Z%2BacGY%2BY%2FS0Bz4EtYAO4C6AF0Fvg9d7u5jMWKL0APgHHe7ub%2FuHVE39wb8kf3V92LVLqHl1w8PWMIs%2FIQ0DzoC9HFxz0zlkuC8oiJwQjmwcd9s5Z6RR0yoIiC5iJLLmL0PEFh73frHRKOmVOkWWYCSmCG3VPh71z7nRKljo5RZYjEybhgNU5fe7%2BpFPklEVOmRcEE8GEBCbI6myCGXkWKPKMYIZMgDfZNaCZEYJhJizUqWkWFCAUQWJfSpx7CwQwKWqYkLc0ra2Ynkc9kNWYI58qHfOSiSDD8VRb0HZNisEkkLCoheTTPYpYTwKz2pqn71SPN84l0dh2R1Olqadg1D5cmlVEJDPEqXjdjkBOlvaRm7dqokqGceI%2BXjXxGJglZUXXMSW%2FbSaqWW2mHmPaR27PW3UE9WzaOVbuVO64e%2BtRVBMekwCoJhXX4zHXk4rJxJslMUApsgHA1suHXA5HXA2HjK5HTKp6hHFaAXi63%2B2v7bxZXy1yOOkP0hKLIDV%2FrgBcAqP9bn9tZ3t9tcjg5HSQNt0IFjCLir%2Fa8Mft9dUic076g5QAVB5B5sF5cL6f%2FqWaOONx1YALYPj24w%2FD0b%2BZs0e6aFvAu%2FbZmwcCvAcetw%2Fpf3gLrPIAPHPVAAAAAElFTkSuQmCC");
				titleBarLeft.setScale(true);
				titleBarLeft.setHeight(28);
				var titleBarSpan = new qx.ui.basic.Image("%2FwD%2FoL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oJBBMSEx8pTOsAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAGpJREFUCNdFzLEJwlAAhOH%2F%2FiAhSaGtI2QFd3GONI7jHhnIJiSgSIpnER42x8F3HMDMc7oVrpe%2BeB467LsW21ODRiRBAyapQTAGBYxiAD3GwUSM1Jaq8P%2BrkAMKfr47rtsbX8uCj%2FsIwPwDxxsQYxM1b7kAAAAASUVORK5CYII%3D");
				titleBarSpan.setScale(true);
				titleBarSpan.setAllowGrowX(true);
				titleBarSpan.setHeight(28);

				var titleBarOrnmt = new qx.ui.basic.Image("webfrontend/ui/win_mainoverlay_ornament.png");
				titleBarOrnmt.setHeight(22);
				titleBarOrnmt.setWidth(148);

				this.contLabel = new qx.ui.basic.Label().set({font: "bold"});
				this.contLabel.setTextColor("text-gold");

				this.coordLabel = new qx.ui.basic.Label().set({font: "bold"});
				this.coordLabel.setTextColor("text-gold");
				
				btn = new qx.ui.form.Button(null,"webfrontend/ui/icons/icon_chat_resize_minimize.png").set({appearance: "button-text-small", padding: [0,0,0,0]});
				btn.addListener("execute", this.minimizeMap, this);

				this.titleBar.add(titleBarLeft,{top: 0, bottom: 0, left: 0});
				this.titleBar.add(titleBarSpan,{top: 0, bottom: 0, left: 10, right: 0});
				this.titleBar.add(titleBarOrnmt,{top: 2, right: 5});
				this.titleBar.add(this.contLabel,{bottom: 7, left: 8});
				this.titleBar.add(this.coordLabel,{bottom: 7, left: 33});
				this.titleBar.add(btn, {top: 4, right: 2});
				
				// ----- Drawing area
				this.da = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.da.setHeight(200);
				this.da.setWidth(200);
				this.da.setZIndex(1000);
				
				this.camera = new qx.ui.core.Widget().set({width: 12, height: 10, zIndex: 1001, decorator: new qx.ui.decoration.Single(1, "solid", "#c3a67f")});
				this.da.addListener("mouseup", this.onMapClick, this);
				this.da.add(this.camera);
				
				this.worldGrid = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
				this.worldGrid.setHeight(196);
				this.worldGrid.setWidth(196);
				this.worldGrid.setZIndex(1005);
				this.worldGrid.setVisibility("hidden");
				this.worldCamera = new qx.ui.core.Widget().set({width: 8, height: 8, zIndex: 1006, decorator: new qx.ui.decoration.Single(2, "solid", "#c3a67f")});
				this.worldGrid.add(this.worldCamera);
				this.da.add(this.worldGrid, {left: 2, top: 2});
				
				this.miniMapCont.add(this.da, {top: 28, left: 0});
				this.miniMapCont.add(this.titleBar, {top: 0, left: 0});
				// ----- -----

				// ----- Show MiniMap button
				this.restoreBtn = new qx.ui.form.Button("Map","webfrontend/ui/icons/icon_chat_resize_maximize.gif").set({appearance: "button-text-small", width: 60, height: 25});
				this.restoreBtn.addListener("execute", this.restoreMap, this);
				
				this.miniMapCont.setVisibility("excluded");
				this.clientArea.add(this.miniMapCont);
				this.clientArea.add(this.restoreBtn, {right: 0, top: 0});
				// ----- -----
				
				// ----- Map array
				this.map = new Array(700);
				for (i=0; i<700; i++) {
					this.map[i] = new Array(700);
				}
				p = webfrontend.data.Player.getInstance();
				this.playerCont = new Array();
				for (var ci in p.cities) {
					this.map[p.cities[ci].xPos][p.cities[ci].yPos] = 0;
					this.playerCont.push(Math.floor(p.cities[ci].xPos/100) + Math.floor(p.cities[ci].yPos/100)*10);
				}
				this.drawWorldGrid();
				this.cityPoints = new Array();
				this.prevCont = -1;
				// ----- -----
			},
			members: {
				clientArea: null,
				miniMapCont: null,
				titleBar: null,
				contLabel: null,
				coordLabel: null,
				da: null,
				map: null,
				worldGrid: null,
				worldCamera: null,
				camera: null,
				playerCont: null,
				cityPoints: null,
				restoreBtn: null,
				prevCont: null,
				getContinentPrefix: function() {
					x = y = 0;
					if (LT.a.visMain.mapmode == "r") {
						x = Math.floor(LT.a.cameraPos.x / LT.a.visMain.getTileWidth());
						y = Math.floor(LT.a.cameraPos.y / LT.a.visMain.getTileHeight());
					} else if (LT.a.visMain.mapmode == "c") {
						c = webfrontend.data.City.getInstance();
						x = c.getId() & 0xFFFF;
						y = c.getId() >> 16;
					}
					if (x < 0) x = 0;
					if (x > 699) x = 699;
					if (y < 0) y = 0;
					if (y > 699) y = 699;
					return {
						px:Math.floor(x/100), // prefix x
						py:Math.floor(y/100), // prefix y
						csx:Math.floor(x/100)*100, // cont start x
						csy:Math.floor(y/100)*100, // xont start y
						cx:x, // x
						cy:y // y
					};
				},
				createPoint: function (x, y, clr) {
					var point = new qx.ui.core.Widget();
					point.setBackgroundColor(LT.options.miniMapColors[clr]);
					point.setHeight(2);
					point.setWidth(2);
					this.da.add(point, {
						top: y*2,
						left: x*2
					});
					return point;
				},
				clearMap: function (b) {
					if (b != "c") {
						for (var i=0; i<this.cityPoints.length; i++) {
							x = this.cityPoints[i].x;
							y = this.cityPoints[i].y;
							if (x > b[0] && x < b[1] && y > b[2] && y < b[3]) {
								this.cityPoints[i].p.destroy();
								this.cityPoints.splice(i, 1);
								i--;
							}
						}
					} else {
						for (var i=0; i<this.cityPoints.length; i++)
							this.cityPoints[i].p.destroy();
					}
				},
				drawMap: function(type) {
					//start = new Date().getTime();
					cp = this.getContinentPrefix();
					if (type != "c") {
						bounds = [ cp.cx-15, cp.cx+15, cp.cy-15, cp.cy+15 ];
						this.clearMap(bounds);
					} else {
						bounds = [ cp.csx, cp.csx+100, cp.csy, cp.csy+100 ];
						this.clearMap("c");
						this.cityPoints = new Array();
					}
					this.updateLabels(cp);
					bounds = [
						(bounds[0]<cp.csx?cp.csx:bounds[0]),
						(bounds[1]>cp.csx+100?cp.csx+100:bounds[1]),
						(bounds[2]<cp.csy?cp.csy:bounds[2]),
						(bounds[3]>cp.csy+100?cp.csy+100:bounds[3])
					];
					for (i=bounds[0]; i<bounds[1]; i++) {
						for (j=bounds[2]; j<bounds[3]; j++) {
							if (this.map[i][j] != undefined) {
								if (this.map[i][j] == -1) {
									LT.debug("Undefined at: " + i + ":" + j);
									continue;
								}
								v = this.map[i][j];
								t = Math.floor(v/2);
								if ( ((t == 7 || t == 8) && LT.options.miniMapMark[t] == 1) || (t != 7 && t != 8 && ((LT.options.miniMapMark[t] == (v%2)+1) || LT.options.miniMapMark[t] == 3))) {
									this.cityPoints.push({p:this.createPoint(i%100, j%100, v), x:i, y:j});
								}
							}
						}
					}
					//LT.debug("D: " + (new Date().getTime()-start));
				},
				onMapClick: function(e) {
					if (e.getButton() == "left") {
						try {
							mx = this.da.getContainerLocation()["left"];
							my = this.da.getContainerLocation()["top"];

							mx = e.getViewportLeft() - mx;
							my = e.getViewportTop() - my;
							
							cp = this.getContinentPrefix();
							if (this.worldGrid.getVisibility() == "visible")
								LT.a.setMainView('r', 0, Math.floor(mx/2)*7 * LT.a.visMain.getTileWidth(), Math.floor(my/2)*7 * LT.a.visMain.getTileHeight());
							else
								LT.a.setMainView('r', 0, (cp.csx + mx/2) * LT.a.visMain.getTileWidth(), (cp.csy + my/2) * LT.a.visMain.getTileHeight());
							this.updateCameraPos();
						} catch(e) { LT.debug(e); }
					} else if (e.getButton() == "right") {
						if (this.worldGrid.getVisibility() == "hidden")
							this.worldGrid.setVisibility("visible");
						else
							this.worldGrid.setVisibility("hidden");
					}
				},
				updateContinent: function() {
					//non-castle/castle
					// 0, 1 self
					// 2, 3 alliance 0
					// 4, 5 allied 1
					// 6, 7 enemy 2
					// 8, 9 nap 3
					// 10, 11 other 4
					// 12, 13 lawless
					// 14 moongate
					// 16 shrine
					if (LT.a.visMain.mapmode == "r") {
						p = webfrontend.data.Player.getInstance().getName();
						v = LT.a.visMain.cells;
						//
						// if 'cells' object is empty (new version)
						//
						if (qx.lang.Object.isEmpty(v)) {
							clib = ClientLib.Vis.VisMain.GetInstance();
							region_object = clib.get_Region();
							if (region_object == null || region_object == undefined) return;
							for (var o in region_object) {
								if (region_object[o] != null && region_object[o].hasOwnProperty("d"))
									data_object = region_object[o];
							}
							if (data_object == null || data_object == undefined) return;
							d_object = data_object.d;
							if (d_object == null || d_object == undefined) return;

							for (var n in d_object) {
								data_table = null;
								// this is just way too much, but couldn't find better solution to get obfuscated and version changing variables
								try {
									for (var dob in d_object[n]) {
										if (d_object[n][dob] instanceof Array && d_object[n][dob].length == 32) {
											for (e=0; e<d_object[n][dob].length; e++) {
												r = d_object[n][dob][e];
												if (r == null && typeof r == "object") {
													data_table = d_object[n][dob];
													break;
												} else {
													for (f=0; f<r.length; f++) {
														if (r[f] == null && typeof r[f] == "object") {
															data_table = d_object[n][dob];
															break;
														}
													}
												}
											}
										}
										if (data_table != null) break;
									}
								} catch (e) {
									
								}
								//data_table = d_object[n].SIB;
								if (data_table == null || data_table == undefined) continue;
								for (q=0; q<data_table.length; q++) {
									row = data_table[q];
									for (w=0; w<row.length; w++) {
										if (row[w] != null) {
											aid = 0;
											pln = "";
											if (typeof row[w].get_AllianceId != 'undefined')
												aid = row[w].get_AllianceId();
											if (typeof row[w].get_PlayerName != 'undefined')
												pln = row[w].get_PlayerName();
											crd = row[w].get_Coordinates();
											posX = crd & 0xFFFF;
											posY = crd >> 16;
											uit = row[w].get_UIType();
											// uit - City / LawlessCity / Shrine / Dungeon / Boss / FreeSlot / null (moongate)
											if (/City/.test(uit)) {
												if (/military|palace/i.test(row[w].get_ImagePath())) uit = uit.replace(/City/, "Castle");
											}
											//console.log(aid + ", (" + posX + ":" + posY +"), " + uit);
											if (/Lawless/.test(uit))
												this.map[posX][posY] = this.getCityType((/City/.test(uit) ? 0 : 10), -1);
											else if (pln == p)
												this.map[posX][posY] = this.getCityType((/City/.test(uit) ? 0 : 10), -2);
											else if (pln != p && pln != "")
												this.map[posX][posY] = this.getCityType((/City/.test(uit) ? 0 : 10), aid);
											else if (uit == "Shrine")
												this.map[posX][posY] = 16;
											else if (uit == null)
												this.map[posX][posY] = 14; // moongate
										}
									}
								}
							} // for d_object
						} else {
							for (var id in v) {
								if (v != null) {
									for (var e in v[id].entities) {
										if (!(v[id].entities[e] instanceof webfrontend.vis.WorldTerrain)) {
											if (v[id].entities[e] instanceof webfrontend.vis.WorldCity) {
												if (v[id].entities[e].playerName == "") this.map[v[id].entities[e].getPosX()][v[id].entities[e].getPosY()] = this.getCityType(v[id].entities[e].id, -1);
												else {
													if (v[id].entities[e].playerName != p)
														this.map[v[id].entities[e].getPosX()][v[id].entities[e].getPosY()] = this.getCityType(v[id].entities[e].id, v[id].entities[e].allianceId);
													else if (v[id].entities[e].playerName == p)
														this.map[v[id].entities[e].getPosX()][v[id].entities[e].getPosY()] = this.getCityType(v[id].entities[e].id, -2);
												}
											} else if (v[id].entities[e] instanceof webfrontend.vis.WorldShrine) {
												this.map[(v[id].entities[e].shrineId & 0xFFFF)][(v[id].entities[e].shrineId >> 16)] = 16;
											} else if (v[id].entities[e] instanceof webfrontend.vis.WorldObject) {
												if (v[id].entities[e].image != undefined) {
													if (v[id].entities[e].image.url.indexOf("moongate") != -1)
														this.map[Math.floor(v[id].entities[e].posX/LT.a.visMain.getTileWidth())][Math.ceil(v[id].entities[e].posY/LT.a.visMain.getTileHeight())] = 14;
												}
											}
										}
									}
								}
							}
						} // end else
					}
				},
				updateCameraPos: function() {
					if (LT.options.showMiniMap) {
						cp = this.getContinentPrefix();
						if (LT.a.visMain.mapmode == "r") {
							this.updateLabels(cp);
							this.updateContinent();
							if ((cp.py*10+cp.px) != this.prevCont) {
								this.drawMap("c");
								this.prevCont = cp.py*10+cp.px;
							} else {
								this.drawMap("p");
							}
							camX = ((cp.cx%100)*2)-5;
							camY = ((cp.cy%100)*2)-4;
							if (camX < 0) camX = 0;
							if (camX > 188) camX = 188;
							if (camY < 0) camY = 0;
							if (camY > 188) camY = 188;
							this.camera.set({marginLeft: camX, marginTop: camY});
							this.worldCamera.set({marginLeft: (Math.floor(cp.csx+camX/2)/7)*2-4, marginTop: (Math.floor(cp.csy+camY/2)/7)*2-4});
						} else if (LT.a.visMain.mapmode == "c") {
							this.updateLabels(cp);
							if ((cp.py*10+cp.px) != this.prevCont) {
								this.drawMap("c");
								this.prevCont = cp.py*10+cp.px;
							}
						}
					}
				},
				updateLabels: function(o) {
					this.contLabel.setValue("c" + (o.py*10+o.px));
					this.coordLabel.setValue(o.cx + ":" + o.cy);
				},
				drawWorldGrid: function() {
					cont = new qx.ui.container.Composite(new qx.ui.layout.Grid());
					contStr = "|" + this.playerCont.join("|") + "|";
					for (i=0; i<7; i++) {
						for (j=0; j<7; j++) {
							cell = new qx.ui.basic.Atom(""+j+""+i).set({ textColor: "#ccffcc", backgroundColor: (contStr.indexOf("|"+j+""+i+"|") != -1 ? "#007700":"#005500"), height: 28, width: 28, center: true, font: "bold", decorator: new qx.ui.decoration.Single(1, "solid", "#003300") });
							cont.add(cell, {column: i, row: j});
						}
					}
					this.worldGrid.add(cont);
				},
				minimizeMap: function() {
					this.miniMapCont.setVisibility("excluded");
					this.restoreBtn.setVisibility("visible");
				},
				restoreMap: function() {
					this.miniMapCont.setVisibility("visible");
					this.restoreBtn.setVisibility("excluded");
				},
				getAllyRelation: function(id) {
					if (id == -1) return -1;
					agi = webfrontend.data.Alliance.getInstance();
					if (id > 0 && id == agi.getId()) return 0;
					rd = agi.getRelationData();
					for (r=0; r<rd.length; r++) {
						if (rd[r].a == id) {
							return rd[r].r;
						}
					}
					return 4;
				},
				getCityType: function(cid, aid) {
					ct = -1;
					if ((cid >= 0 && cid <= 7) || (cid >= 30 && cid <= 37)) ct = 2; // non castle city
					else if ((cid >= 10 && cid <= 15) || (cid >= 40 && cid <= 45)) ct = 3; // castle
					else if ((cid >= 20 && cid <= 24) || (cid >= 50 && cid <= 54)) ct = 3; // palace
					if (aid == -1) return ct+10;
					if (aid == -2) return ct-2;
					rt = this.getAllyRelation(aid);
					return (ct == -1) ? -1 : rt*2 + ct;
				}
			}
			// .id in webfrontend.vis.WorldCity
			// noncas nonlaw 0-7
			// cas nonlaw 10-15
			// pal nonlaw 20-24
			
			// noncas law 30-37
			// cas law 40-45
			// pal law 50-54
			
			// noncas ruins 60
			// cas ruins 70
			// pal ruins 80
		});
	}
	
	function LT_checkIfLoaded() {
		try {
			if (typeof qx != 'undefined') {
				a = qx.core.Init.getApplication(); // application
				c = a.cityInfoView;
				ch = a.chat;
				wdst = webfrontend.data.ServerTime.getInstance().refTime;
				if (a && c && ch && wdst) {
					createTweak();
					window.louTweak.main.getInstance().initialize();
				} else
					window.setTimeout(LT_checkIfLoaded, 1000);
			} else {
				window.setTimeout(LT_checkIfLoaded, 1000);
			}
		} catch (e) {
			if (typeof console != 'undefined') console.log(e);
			else if (window.opera) opera.postError(e);
			else GM_log(e);
		}
	}
	if (/lordofultima\.com/i.test(document.domain))
		window.setTimeout(LT_checkIfLoaded, 1000);
			
}

	// injecting, because there seem to be problems when creating game interface with unsafeWindow
	var louTweakScript = document.createElement("script");
		txt = LT_mainFunction.toString();
		louTweakScript.innerHTML = "(" + txt + ")();";
		louTweakScript.type = "text/javascript";
	if (/lordofultima\.com/i.test(document.domain))
		document.getElementsByTagName("head")[0].appendChild(louTweakScript);

	
})();